Fix C# design time projections for complex TagHelper attributes.
- TagHelper attributes that have expressions intermingled within them (resulting in Block elements) resulted in Spans in the attribute being falsely marked as SpanKind.Markup. - Updated tests to account for new SpanKind.Code behavior. - Added complex scenario to validate SpanKind.Code is flowed through to surround attributes. #387
This commit is contained in:
parent
a73867eabe
commit
039062c5eb
|
|
@ -254,7 +254,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
|||
// If we're not after an equal then we should treat the value as if it were a minimized attribute.
|
||||
var attributeValueBuilder = afterEquals ? builder : null;
|
||||
result.AttributeValueNode =
|
||||
CreateMarkupAttribute(name, attributeValueBuilder, result.IsBoundNonStringAttribute);
|
||||
CreateMarkupAttribute(attributeValueBuilder, result.IsBoundNonStringAttribute);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -337,17 +337,45 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
|||
var spanBuilder = new SpanBuilder(child);
|
||||
|
||||
result.AttributeValueNode =
|
||||
CreateMarkupAttribute(name, spanBuilder, result.IsBoundNonStringAttribute);
|
||||
CreateMarkupAttribute(spanBuilder, result.IsBoundNonStringAttribute);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
result.AttributeValueNode = block;
|
||||
result.AttributeValueNode = ConvertToMarkupAttributeBlock(block, result.IsBoundNonStringAttribute);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Block ConvertToMarkupAttributeBlock(Block block, bool isBoundNonStringAttribute)
|
||||
{
|
||||
var blockBuilder = new BlockBuilder
|
||||
{
|
||||
ChunkGenerator = block.ChunkGenerator,
|
||||
Type = block.Type
|
||||
};
|
||||
|
||||
foreach (var child in block.Children)
|
||||
{
|
||||
SyntaxTreeNode markupAttributeChild;
|
||||
|
||||
if (child.IsBlock)
|
||||
{
|
||||
markupAttributeChild = ConvertToMarkupAttributeBlock((Block)child, isBoundNonStringAttribute);
|
||||
}
|
||||
else
|
||||
{
|
||||
var spanBuilder = new SpanBuilder((Span)child);
|
||||
markupAttributeChild = CreateMarkupAttribute(spanBuilder, isBoundNonStringAttribute);
|
||||
}
|
||||
|
||||
blockBuilder.Children.Add(markupAttributeChild);
|
||||
}
|
||||
|
||||
return blockBuilder.Build();
|
||||
}
|
||||
|
||||
private static Block RebuildChunkGenerators(Block block)
|
||||
{
|
||||
var builder = new BlockBuilder(block);
|
||||
|
|
@ -440,10 +468,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
|||
return nodeStart + firstNonWhitespaceSymbol.Start;
|
||||
}
|
||||
|
||||
private static SyntaxTreeNode CreateMarkupAttribute(
|
||||
string name,
|
||||
SpanBuilder builder,
|
||||
bool isBoundNonStringAttribute)
|
||||
private static SyntaxTreeNode CreateMarkupAttribute(SpanBuilder builder, bool isBoundNonStringAttribute)
|
||||
{
|
||||
Span value = null;
|
||||
|
||||
|
|
|
|||
|
|
@ -385,6 +385,12 @@ namespace Microsoft.AspNet.Razor.Test.Framework
|
|||
return Builder.Build();
|
||||
}
|
||||
|
||||
public SpanConstructor As(SpanKind spanKind)
|
||||
{
|
||||
Builder.Kind = spanKind;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpanConstructor With(ISpanChunkGenerator generator)
|
||||
{
|
||||
Builder.ChunkGenerator = generator;
|
||||
|
|
|
|||
|
|
@ -603,6 +603,58 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
|||
new MarkupBlock(factory.Markup("Time:"), dateTimeNow))
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<person age=\"1 + @value + 2\" birthday='(bool)@Bag[\"val\"] ? @@DateTime : @DateTime.Now'/>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock("person",
|
||||
selfClosing: true,
|
||||
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
|
||||
{
|
||||
new KeyValuePair<string, SyntaxTreeNode>(
|
||||
"age",
|
||||
new MarkupBlock(
|
||||
factory.CodeMarkup("1"),
|
||||
factory.CodeMarkup(" +"),
|
||||
new MarkupBlock(
|
||||
factory.CodeMarkup(" "),
|
||||
new ExpressionBlock(
|
||||
factory.CodeTransition().As(SpanKind.Code),
|
||||
factory
|
||||
.Code("value")
|
||||
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace))),
|
||||
factory.CodeMarkup(" +"),
|
||||
factory.CodeMarkup(" 2"))),
|
||||
new KeyValuePair<string, SyntaxTreeNode>(
|
||||
"birthday",
|
||||
new MarkupBlock(
|
||||
factory.CodeMarkup("(bool)"),
|
||||
new MarkupBlock(
|
||||
new ExpressionBlock(
|
||||
factory.CodeTransition().As(SpanKind.Code),
|
||||
factory
|
||||
.Code("Bag[\"val\"]")
|
||||
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace))),
|
||||
factory.CodeMarkup(" ?"),
|
||||
new MarkupBlock(
|
||||
factory.CodeMarkup(" @").Accepts(AcceptedCharacters.None),
|
||||
factory.CodeMarkup("@")
|
||||
.With(SpanChunkGenerator.Null)
|
||||
.Accepts(AcceptedCharacters.None)),
|
||||
factory.CodeMarkup("DateTime"),
|
||||
factory.CodeMarkup(" :"),
|
||||
new MarkupBlock(
|
||||
factory.CodeMarkup(" "),
|
||||
new ExpressionBlock(
|
||||
factory.CodeTransition().As(SpanKind.Code),
|
||||
factory
|
||||
.Code("DateTime.Now")
|
||||
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)))
|
||||
))
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<person age=\"12\" birthday=\"DateTime.Now\" name=\"Time: @DateTime.Now\" />",
|
||||
new MarkupBlock(
|
||||
|
|
@ -675,17 +727,21 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
|||
"age",
|
||||
new MarkupBlock(
|
||||
new MarkupBlock(
|
||||
factory.Markup("@").Accepts(AcceptedCharacters.None),
|
||||
factory.Markup("@")
|
||||
factory.CodeMarkup("@").Accepts(AcceptedCharacters.None),
|
||||
factory.CodeMarkup("@")
|
||||
.With(SpanChunkGenerator.Null)
|
||||
.Accepts(AcceptedCharacters.None)),
|
||||
new MarkupBlock(
|
||||
factory.EmptyHtml(),
|
||||
factory.EmptyHtml().As(SpanKind.Code),
|
||||
new ExpressionBlock(
|
||||
factory.CodeTransition(),
|
||||
factory.MetaCode("(").Accepts(AcceptedCharacters.None),
|
||||
factory.CodeTransition().As(SpanKind.Code),
|
||||
factory.MetaCode("(")
|
||||
.Accepts(AcceptedCharacters.None)
|
||||
.As(SpanKind.Code),
|
||||
factory.Code("11+1").AsExpression(),
|
||||
factory.MetaCode(")").Accepts(AcceptedCharacters.None))))),
|
||||
factory.MetaCode(")")
|
||||
.Accepts(AcceptedCharacters.None)
|
||||
.As(SpanKind.Code))))),
|
||||
new KeyValuePair<string, SyntaxTreeNode>(
|
||||
"birthday",
|
||||
factory.CodeMarkup("DateTime.Now")),
|
||||
|
|
@ -1653,13 +1709,13 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
|||
"bound",
|
||||
new MarkupBlock(
|
||||
new MarkupBlock(
|
||||
factory.Markup(" "),
|
||||
factory.CodeMarkup(" "),
|
||||
new ExpressionBlock(
|
||||
factory.CodeTransition(),
|
||||
factory.CodeTransition().As(SpanKind.Code),
|
||||
factory.Code("true")
|
||||
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace))),
|
||||
factory.Markup(" ")))
|
||||
factory.CodeMarkup(" ")))
|
||||
}
|
||||
})),
|
||||
new RazorError[0]
|
||||
|
|
@ -1677,13 +1733,17 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
|||
"bound",
|
||||
new MarkupBlock(
|
||||
new MarkupBlock(
|
||||
factory.Markup(" "),
|
||||
factory.CodeMarkup(" "),
|
||||
new ExpressionBlock(
|
||||
factory.CodeTransition(),
|
||||
factory.MetaCode("(").Accepts(AcceptedCharacters.None),
|
||||
factory.CodeTransition().As(SpanKind.Code),
|
||||
factory.MetaCode("(")
|
||||
.Accepts(AcceptedCharacters.None)
|
||||
.As(SpanKind.Code),
|
||||
factory.Code("true").AsExpression(),
|
||||
factory.MetaCode(")").Accepts(AcceptedCharacters.None))),
|
||||
factory.Markup(" ")))
|
||||
factory.MetaCode(")")
|
||||
.Accepts(AcceptedCharacters.None)
|
||||
.As(SpanKind.Code))),
|
||||
factory.CodeMarkup(" ")))
|
||||
}
|
||||
})),
|
||||
new RazorError[0]
|
||||
|
|
|
|||
|
|
@ -1131,7 +1131,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
new MarkupBlock(
|
||||
new MarkupBlock(
|
||||
new ExpressionBlock(
|
||||
factory.CodeTransition(),
|
||||
factory.CodeTransition().As(SpanKind.Code),
|
||||
factory.Code("DateTime.Now")
|
||||
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)))))
|
||||
|
|
@ -1153,7 +1153,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
new MarkupBlock(
|
||||
new MarkupBlock(
|
||||
new ExpressionBlock(
|
||||
factory.CodeTransition(),
|
||||
factory.CodeTransition().As(SpanKind.Code),
|
||||
factory.Code("DateTime.Now")
|
||||
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)))))
|
||||
|
|
@ -1174,12 +1174,12 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
"bound",
|
||||
new MarkupBlock(
|
||||
new MarkupBlock(
|
||||
factory.Markup("@").Accepts(AcceptedCharacters.None),
|
||||
factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharacters.None)),
|
||||
factory.CodeMarkup("@").Accepts(AcceptedCharacters.None),
|
||||
factory.CodeMarkup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharacters.None)),
|
||||
new MarkupBlock(
|
||||
factory.EmptyHtml(),
|
||||
factory.EmptyHtml().As(SpanKind.Code),
|
||||
new ExpressionBlock(
|
||||
factory.CodeTransition(),
|
||||
factory.CodeTransition().As(SpanKind.Code),
|
||||
factory.Code("DateTime.Now")
|
||||
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)))))
|
||||
|
|
|
|||
Loading…
Reference in New Issue