From 47577fd93602bfbd2938e92a1d3f34a93fb29406 Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Mon, 18 May 2015 15:42:49 -0700 Subject: [PATCH] [Fixes #379] Ignoring whitespace at the end of text tag --- .../Parser/HtmlMarkupParser.Block.cs | 18 ++++++++- .../Generator/CSharpTagHelperRenderingTest.cs | 40 ++++++++++--------- .../Generator/RazorCodeGeneratorTest.cs | 2 +- .../Parser/CSharp/CSharpToMarkupSwitchTest.cs | 7 ++-- .../Parser/Html/HtmlBlockTest.cs | 4 +- .../TagHelperParseTreeRewriterTest.cs | 2 +- .../CS/Output/CodeBlockWithTextElement.cs | 30 +++++++++----- .../CS/Output/ComplexTagHelpers.DesignTime.cs | 12 ++++++ .../CS/Output/ComplexTagHelpers.cs | 16 +++++++- .../CodeGenerator/CS/Output/InlineBlocks.cs | 10 ++++- .../CodeGenerator/CS/Output/ResolveUrl.cs | 10 ++++- .../CS/Source/CodeBlockWithTextElement.cshtml | 4 +- 12 files changed, 108 insertions(+), 47 deletions(-) diff --git a/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.Block.cs b/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.Block.cs index 005a2ee972..08f818c517 100644 --- a/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.Block.cs +++ b/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.Block.cs @@ -1039,7 +1039,7 @@ namespace Microsoft.AspNet.Razor.Parser { tags.Pop(); } - Tuple tag = tags.Pop(); + var tag = tags.Pop(); Context.OnError(tag.Item2, RazorResources.FormatParseError_MissingEndTag(tag.Item1.Content)); } else if (complete) @@ -1049,7 +1049,21 @@ namespace Microsoft.AspNet.Razor.Parser tags.Clear(); if (!Context.DesignTimeMode) { - AcceptWhile(HtmlSymbolType.WhiteSpace); + if (Context.LastSpan.Kind == SpanKind.Transition) + { + // Output current span content as markup. + Output(SpanKind.Markup); + + // Accept and mark the whitespace at the end of a tag as code. + AcceptWhile(HtmlSymbolType.WhiteSpace); + Span.CodeGenerator = new StatementCodeGenerator(); + Output(SpanKind.Code); + } + else + { + AcceptWhile(HtmlSymbolType.WhiteSpace); + } + if (!EndOfFile && CurrentSymbol.Type == HtmlSymbolType.NewLine) { AcceptAndMoveNext(); diff --git a/test/Microsoft.AspNet.Razor.Test/Generator/CSharpTagHelperRenderingTest.cs b/test/Microsoft.AspNet.Razor.Test/Generator/CSharpTagHelperRenderingTest.cs index 94594412dc..1356d6cb08 100644 --- a/test/Microsoft.AspNet.Razor.Test/Generator/CSharpTagHelperRenderingTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/Generator/CSharpTagHelperRenderingTest.cs @@ -381,25 +381,27 @@ namespace Microsoft.AspNet.Razor.Test.Generator BuildLineMapping(463, 15, 2127, 79, 63, 4), BuildLineMapping(507, 16, 31, 2334, 86, 6, 30), BuildLineMapping(574, 17, 30, 2683, 95, 0, 10), - BuildLineMapping(607, 17, 63, 2765, 101, 0, 8), - BuildLineMapping(638, 17, 94, 2845, 107, 0, 1), - BuildLineMapping(645, 18, 3099, 116, 0, 15), - BuildLineMapping(163, 7, 32, 3248, 123, 6, 12), - BuildLineMapping(725, 21, 3331, 128, 0, 12), - BuildLineMapping(739, 21, 3429, 134, 14, 21), - BuildLineMapping(793, 22, 30, 3686, 142, 28, 7), - BuildLineMapping(691, 20, 17, 3842, 148, 19, 23), - BuildLineMapping(714, 20, 40, 3865, 148, 42, 7), - BuildLineMapping(903, 25, 30, 4107, 155, 28, 30), - BuildLineMapping(837, 24, 16, 4286, 161, 19, 8), - BuildLineMapping(846, 24, 25, 4294, 161, 27, 23), - BuildLineMapping(1032, 28, 4552, 168, 28, 30), - BuildLineMapping(970, 27, 16, 4731, 174, 19, 30), - BuildLineMapping(1162, 31, 4996, 181, 28, 3), - BuildLineMapping(1167, 31, 33, 4999, 181, 31, 27), - BuildLineMapping(1195, 31, 61, 5026, 181, 58, 10), - BuildLineMapping(1100, 30, 18, 5185, 187, 19, 29), - BuildLineMapping(1237, 34, 5285, 192, 0, 1), + BuildLineMapping(606, 17, 62, 2765, 101, 0, 1), + BuildLineMapping(607, 17, 63, 2838, 107, 0, 8), + BuildLineMapping(637, 17, 93, 2918, 113, 0, 1), + BuildLineMapping(638, 17, 94, 2991, 119, 0, 1), + BuildLineMapping(645, 18, 0, 3245, 128, 0, 15), + BuildLineMapping(163, 7, 32, 3394, 135, 6, 12), + BuildLineMapping(725, 21, 0, 3477, 140, 0, 12), + BuildLineMapping(739, 21, 14, 3575, 146, 14, 21), + BuildLineMapping(793, 22, 30, 3832, 154, 28, 7), + BuildLineMapping(691, 20, 17, 3988, 160, 19, 23), + BuildLineMapping(714, 20, 40, 4011, 160, 42, 7), + BuildLineMapping(903, 25, 30, 4253, 167, 28, 30), + BuildLineMapping(837, 24, 16, 4432, 173, 19, 8), + BuildLineMapping(846, 24, 25, 4440, 173, 27, 23), + BuildLineMapping(1032, 28, 28, 4698, 180, 28, 30), + BuildLineMapping(970, 27, 16, 4877, 186, 19, 30), + BuildLineMapping(1162, 31, 28, 5142, 193, 28, 3), + BuildLineMapping(1167, 31, 33, 5145, 193, 31, 27), + BuildLineMapping(1195, 31, 61, 5172, 193, 58, 10), + BuildLineMapping(1100, 30, 18, 5331, 199, 19, 29), + BuildLineMapping(1237, 34, 0, 5431, 204, 0, 1), } }, { diff --git a/test/Microsoft.AspNet.Razor.Test/Generator/RazorCodeGeneratorTest.cs b/test/Microsoft.AspNet.Razor.Test/Generator/RazorCodeGeneratorTest.cs index 8701f1494e..672479889e 100644 --- a/test/Microsoft.AspNet.Razor.Test/Generator/RazorCodeGeneratorTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/Generator/RazorCodeGeneratorTest.cs @@ -190,7 +190,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator Assert.Equal(expectedOutput, textOutput); #endif - IEnumerable generatedSpans = results.Document.Flatten(); + var generatedSpans = results.Document.Flatten(); foreach (var span in generatedSpans) { diff --git a/test/Microsoft.AspNet.Razor.Test/Parser/CSharp/CSharpToMarkupSwitchTest.cs b/test/Microsoft.AspNet.Razor.Test/Parser/CSharp/CSharpToMarkupSwitchTest.cs index c9a8e5e7a8..a6167cd7fa 100644 --- a/test/Microsoft.AspNet.Razor.Test/Parser/CSharp/CSharpToMarkupSwitchTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/Parser/CSharp/CSharpToMarkupSwitchTest.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNet.Razor.Editor; +using Microsoft.AspNet.Razor.Generator; using Microsoft.AspNet.Razor.Parser; using Microsoft.AspNet.Razor.Parser.SyntaxTree; using Microsoft.AspNet.Razor.Test.Framework; @@ -583,7 +584,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp Factory.Markup(";").Accepts(AcceptedCharacters.None), new MarkupTagBlock( Factory.MarkupTransition("").Accepts(AcceptedCharacters.None)), - Factory.Markup(" ").Accepts(AcceptedCharacters.None) + Factory.CodeMarkup(" ").With(new StatementCodeGenerator()).Accepts(AcceptedCharacters.None) ), Factory.Code("}").AsStatement())); } @@ -603,7 +604,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp Factory.Markup(";").Accepts(AcceptedCharacters.None), new MarkupTagBlock( Factory.MarkupTransition("").Accepts(AcceptedCharacters.None)), - Factory.Markup(" ").Accepts(AcceptedCharacters.None) + Factory.CodeMarkup(" ").With(new StatementCodeGenerator()).Accepts(AcceptedCharacters.None) ), Factory.Code("} ").AsStatement(), Factory.MetaCode("}").Accepts(AcceptedCharacters.None))); @@ -646,7 +647,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp ), new MarkupTagBlock( Factory.MarkupTransition("").Accepts(AcceptedCharacters.None)), - Factory.Markup(Environment.NewLine).Accepts(AcceptedCharacters.None) + Factory.Markup(Environment.NewLine).With(new StatementCodeGenerator()).Accepts(AcceptedCharacters.None) ), Factory.Code($" }}{Environment.NewLine} if(!false) {{{Environment.NewLine}").AsStatement(), new MarkupBlock( diff --git a/test/Microsoft.AspNet.Razor.Test/Parser/Html/HtmlBlockTest.cs b/test/Microsoft.AspNet.Razor.Test/Parser/Html/HtmlBlockTest.cs index 6fec05e5ea..a815119462 100644 --- a/test/Microsoft.AspNet.Razor.Test/Parser/Html/HtmlBlockTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/Parser/Html/HtmlBlockTest.cs @@ -495,7 +495,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.Html Factory.Markup(" Baz"), new MarkupTagBlock( Factory.MarkupTransition("")), - Factory.Markup(" ").Accepts(AcceptedCharacters.None) + Factory.CodeMarkup(" ").With(new StatementCodeGenerator()).Accepts(AcceptedCharacters.None) )); } @@ -516,7 +516,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.Html Factory.Markup("").Accepts(AcceptedCharacters.None)), new MarkupTagBlock( Factory.MarkupTransition("")), - Factory.Markup(" ").Accepts(AcceptedCharacters.None) + Factory.CodeMarkup(" ").With(new StatementCodeGenerator()).Accepts(AcceptedCharacters.None) )); } diff --git a/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperParseTreeRewriterTest.cs b/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperParseTreeRewriterTest.cs index bb96653ccb..2727b92501 100644 --- a/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperParseTreeRewriterTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperParseTreeRewriterTest.cs @@ -4496,7 +4496,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers factory.Markup("Foo").Accepts(AcceptedCharacters.None), new MarkupTagBlock( factory.MarkupTransition("")), - factory.Markup(" ").Accepts(AcceptedCharacters.None)), + factory.CodeMarkup(" ").With(new StatementCodeGenerator()).Accepts(AcceptedCharacters.None)), factory.Code("foo++; } while (foo);").AsStatement().Accepts(AcceptedCharacters.None))); var currentFormattedString = "

"; diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/CodeBlockWithTextElement.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/CodeBlockWithTextElement.cs index b52e32211f..e40a37c354 100644 --- a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/CodeBlockWithTextElement.cs +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/CodeBlockWithTextElement.cs @@ -1,4 +1,4 @@ -#pragma checksum "CodeBlockWithTextElement.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "740b5af27dd6c6ff0e88b39a02d4bf1a38fcdc0b" +#pragma checksum "CodeBlockWithTextElement.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "13e48ff59aab8106ceb68dd4a10b0bdf10c322fc" namespace TestOutput { using System; @@ -21,14 +21,16 @@ namespace TestOutput #line default #line hidden - Instrumentation.BeginContext(26, 1, false); + Instrumentation.BeginContext(25, 3, true); + WriteLiteral("foo"); + Instrumentation.EndContext(); #line 2 "CodeBlockWithTextElement.cshtml" - Write(a); + #line default #line hidden - Instrumentation.EndContext(); - Instrumentation.BeginContext(34, 2, true); + + Instrumentation.BeginContext(38, 2, true); WriteLiteral("\r\n"); Instrumentation.EndContext(); #line 3 "CodeBlockWithTextElement.cshtml" @@ -37,22 +39,28 @@ namespace TestOutput #line default #line hidden - Instrumentation.BeginContext(60, 1, false); + Instrumentation.BeginContext(63, 4, true); + WriteLiteral("bar "); + Instrumentation.EndContext(); + Instrumentation.BeginContext(69, 3, false); #line 3 "CodeBlockWithTextElement.cshtml" - Write(b); + Write(a+b); #line default #line hidden Instrumentation.EndContext(); - Instrumentation.BeginContext(68, 2, true); - WriteLiteral("\r\n"); - Instrumentation.EndContext(); +#line 3 "CodeBlockWithTextElement.cshtml" + + +#line default +#line hidden + #line 4 "CodeBlockWithTextElement.cshtml" #line default #line hidden - Instrumentation.BeginContext(71, 2, true); + Instrumentation.BeginContext(83, 2, true); WriteLiteral("\r\n"); Instrumentation.EndContext(); } diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ComplexTagHelpers.DesignTime.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ComplexTagHelpers.DesignTime.cs index 433d42d132..952252b91a 100644 --- a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ComplexTagHelpers.DesignTime.cs +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ComplexTagHelpers.DesignTime.cs @@ -95,12 +95,24 @@ __o = true ? "checkbox" : "anything"; #line 18 "ComplexTagHelpers.cshtml" if(true) { +#line default +#line hidden + +#line 18 "ComplexTagHelpers.cshtml" + + #line default #line hidden #line 18 "ComplexTagHelpers.cshtml" } else { +#line default +#line hidden + +#line 18 "ComplexTagHelpers.cshtml" + + #line default #line hidden diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ComplexTagHelpers.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ComplexTagHelpers.cs index 430b9c41dd..70180ee131 100644 --- a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ComplexTagHelpers.cs +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ComplexTagHelpers.cs @@ -160,14 +160,26 @@ if(true) { #line default #line hidden - WriteLiteral("checkbox "); + WriteLiteral("checkbox"); +#line 18 "ComplexTagHelpers.cshtml" + + +#line default +#line hidden + #line 18 "ComplexTagHelpers.cshtml" } else { #line default #line hidden - WriteLiteral("anything "); + WriteLiteral("anything"); +#line 18 "ComplexTagHelpers.cshtml" + + +#line default +#line hidden + #line 18 "ComplexTagHelpers.cshtml" } diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/InlineBlocks.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/InlineBlocks.cs index addae5b033..babca7b88f 100644 --- a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/InlineBlocks.cs +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/InlineBlocks.cs @@ -41,9 +41,15 @@ WriteTo(__razor_attribute_value_writer, link); #line default #line hidden - Instrumentation.BeginContext(84, 2, true); - WriteLiteralTo(__razor_attribute_value_writer, "# "); + Instrumentation.BeginContext(84, 1, true); + WriteLiteralTo(__razor_attribute_value_writer, "#"); Instrumentation.EndContext(); +#line 2 "InlineBlocks.cshtml" + + +#line default +#line hidden + #line 2 "InlineBlocks.cshtml" } diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ResolveUrl.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ResolveUrl.cs index db852f50d0..71c1f8b2a7 100644 --- a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ResolveUrl.cs +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ResolveUrl.cs @@ -81,9 +81,15 @@ namespace TestOutput Instrumentation.EndContext(); WriteAttribute("href", Tuple.Create(" href=\"", 387), Tuple.Create("\"", 442), Tuple.Create(Tuple.Create("", 394), Tuple.Create(Href("~/A+Really(Crazy),Url.Is:This/"), 394), false), Tuple.Create(Tuple.Create("", 424), Tuple.Create(product.id, 424), false), Tuple.Create(Tuple.Create("", 435), Tuple.Create("/Detail", 435), true)); - Instrumentation.BeginContext(443, 23, true); - WriteLiteral(">Crazy Url!\r\n \r\n"); + Instrumentation.BeginContext(443, 21, true); + WriteLiteral(">Crazy Url!\r\n "); Instrumentation.EndContext(); +#line 12 "ResolveUrl.cshtml" + + +#line default +#line hidden + #line 13 "ResolveUrl.cshtml" #line default diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Source/CodeBlockWithTextElement.cshtml b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Source/CodeBlockWithTextElement.cshtml index c85dc419a1..9c34a940eb 100644 --- a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Source/CodeBlockWithTextElement.cshtml +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Source/CodeBlockWithTextElement.cshtml @@ -1,4 +1,4 @@ @{ - var a = 1; @a - var b = 1; @b + var a = 1; foo + var b = 1; bar @(a+b) }