Remove ~/ handling from core Razor.

- Removed parsing, chunk generation and code generation.
- Removed related tests.
- Did not modify existing unrelated tests with ~/ since it's just plain text and may be valid for end-users.

#427
This commit is contained in:
N. Taylor Mullen 2015-07-15 16:49:05 -07:00
parent a8fd85db1e
commit 48a6b567d6
18 changed files with 18 additions and 643 deletions

View File

@ -132,14 +132,6 @@ namespace Microsoft.AspNet.Razor.Chunks
}, association);
}
public void AddResolveUrlChunk(string url, SyntaxTreeNode association)
{
AddChunk(new ResolveUrlChunk
{
Url = url
}, association);
}
public void AddSetBaseTypeChunk(string typeName, SyntaxTreeNode association)
{
AddChunk(new SetBaseTypeChunk

View File

@ -1,28 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
namespace Microsoft.AspNet.Razor.Chunks.Generators
{
public class ResolveUrlChunkGenerator : SpanChunkGenerator
{
public override void GenerateChunk(Span target, ChunkGeneratorContext context)
{
// Check if the host supports it
if (string.IsNullOrEmpty(context.Host.GeneratedClassContext.ResolveUrlMethodName))
{
// Nope, just use the default MarkupChunkGenerator behavior
new MarkupChunkGenerator().GenerateChunk(target, context);
return;
}
context.ChunkTreeBuilder.AddResolveUrlChunk(target.Content, target);
}
public override string ToString()
{
return "VirtualPath";
}
}
}

View File

@ -1,10 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNet.Razor.Chunks
{
public class ResolveUrlChunk : Chunk
{
public string Url { get; set; }
}
}

View File

@ -136,9 +136,6 @@ namespace Microsoft.AspNet.Razor.CodeGenerators
public string WriteAttributeMethodName { get; set; }
public string WriteAttributeToMethodName { get; set; }
[SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Property is not a URL property")]
public string ResolveUrlMethodName { get; set; }
public bool AllowSections
{
get { return !string.IsNullOrEmpty(DefineSectionMethodName); }

View File

@ -94,45 +94,6 @@ namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
Writer.WriteEndMethodInvocation(false).WriteLine();
}
protected override void Visit(ResolveUrlChunk chunk)
{
if (!Context.Host.DesignTimeMode && string.IsNullOrEmpty(chunk.Url))
{
return;
}
var generateInstrumentation = ShouldGenerateInstrumentationForExpressions();
if (generateInstrumentation)
{
// Add a non-literal context call (non-literal because the expanded URL will not match the source
// character-by-character)
Writer.WriteStartInstrumentationContext(Context, chunk.Association, isLiteral: false);
}
if (!string.IsNullOrEmpty(chunk.Url) && !Context.Host.DesignTimeMode)
{
if (Context.ExpressionRenderingMode == ExpressionRenderingMode.WriteToOutput)
{
RenderPreWriteStart();
}
Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.ResolveUrlMethodName)
.WriteStringLiteral(chunk.Url)
.WriteEndMethodInvocation(endLine: false);
if (Context.ExpressionRenderingMode == ExpressionRenderingMode.WriteToOutput)
{
Writer.WriteEndMethodInvocation();
}
}
if (generateInstrumentation)
{
Writer.WriteEndInstrumentationContext(Context);
}
}
protected override void Visit(LiteralChunk chunk)
{
if (Context.Host.DesignTimeMode || string.IsNullOrEmpty(chunk.Text))

View File

@ -92,19 +92,6 @@ namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
RenderCode(chunk.Text, (Span)chunk.Association);
}
/// <summary>
/// Writes code for the given <paramref name="chunk"/>.
/// </summary>
/// <param name="chunk">The <see cref="ResolveUrlChunk"/> to render.</param>
/// <remarks>
/// Allowed to support future C# extensions. Likely "~/..." will lead to a C# compilation error but that is up
/// to the compiler.
/// </remarks>
protected override void Visit(ResolveUrlChunk chunk)
{
RenderCode(chunk.Url, (Span)chunk.Association);
}
/// <summary>
/// Writes code for the given <paramref name="chunk"/>.
/// </summary>

View File

@ -61,10 +61,6 @@ namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
{
Visit((RemoveTagHelperChunk)chunk);
}
else if (chunk is ResolveUrlChunk)
{
Visit((ResolveUrlChunk)chunk);
}
else if (chunk is TypeMemberChunk)
{
Visit((TypeMemberChunk)chunk);
@ -117,7 +113,6 @@ namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
protected abstract void Visit(CodeAttributeChunk chunk);
protected abstract void Visit(SectionChunk chunk);
protected abstract void Visit(TypeMemberChunk chunk);
protected abstract void Visit(ResolveUrlChunk chunk);
protected abstract void Visit(SetBaseTypeChunk chunk);
protected abstract void Visit(TemplateChunk chunk);
protected abstract void Visit(ExpressionBlockChunk chunk);

View File

@ -59,9 +59,6 @@ namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
protected override void Visit(TypeMemberChunk chunk)
{
}
protected override void Visit(ResolveUrlChunk chunk)
{
}
protected override void Visit(SetBaseTypeChunk chunk)
{
}

View File

@ -616,20 +616,6 @@ namespace Microsoft.AspNet.Razor.Parser
}
}
}
else if (At(HtmlSymbolType.Text) &&
CurrentSymbol.Content.Length > 0 &&
CurrentSymbol.Content[0] == '~' &&
NextIs(HtmlSymbolType.ForwardSlash))
{
Accept(prefix);
// Virtual Path value
var valueStart = CurrentLocation;
VirtualPath();
Span.ChunkGenerator = new LiteralAttributeChunkGenerator(
prefix.GetContent(prefixStart),
new LocationTagged<SpanChunkGenerator>(new ResolveUrlChunkGenerator(), valueStart));
}
else
{
Accept(prefix);
@ -676,18 +662,6 @@ namespace Microsoft.AspNet.Razor.Parser
sym.Type == HtmlSymbolType.NewLine;
}
private void VirtualPath()
{
Assert(HtmlSymbolType.Text);
Debug.Assert(CurrentSymbol.Content.Length > 0 && CurrentSymbol.Content[0] == '~');
// Parse until a transition symbol, whitespace, newline or quote. We support only a fairly minimal subset of Virtual Paths
AcceptUntil(HtmlSymbolType.Transition, HtmlSymbolType.WhiteSpace, HtmlSymbolType.NewLine, HtmlSymbolType.SingleQuote, HtmlSymbolType.DoubleQuote);
// Output a Virtual Path span
Span.EditHandler.EditorHints = EditorHints.VirtualPath;
}
private void RecoverToEndOfTag()
{
// Accept until ">", "/" or "<", but parse code

View File

@ -28,7 +28,6 @@ namespace Microsoft.AspNet.Razor.Test.Generator
}
private const string TestPhysicalPath = @"C:\Bar.cshtml";
private const string TestVirtualPath = "~/Foo/Bar.cshtml";
[Fact]
public void ConstructorRequiresNonNullClassName()
@ -69,7 +68,6 @@ namespace Microsoft.AspNet.Razor.Test.Generator
[InlineData("RazorComments")]
[InlineData("InlineBlocks")]
[InlineData("ConditionalAttributes")]
[InlineData("ResolveUrl")]
[InlineData("Await")]
[InlineData("CodeBlockWithTextElement")]
public void CSharpChunkGeneratorCorrectlyGeneratesRunTimeCode(string testType)

View File

@ -152,19 +152,17 @@ namespace Microsoft.AspNet.Razor.Test.Generator
host.DefaultClassName = name;
// Add support for templates, etc.
host.GeneratedClassContext = new GeneratedClassContext(GeneratedClassContext.DefaultExecuteMethodName,
GeneratedClassContext.DefaultWriteMethodName,
GeneratedClassContext.DefaultWriteLiteralMethodName,
"WriteTo",
"WriteLiteralTo",
"Template",
"DefineSection",
"Instrumentation.BeginContext",
"Instrumentation.EndContext",
new GeneratedTagHelperContext())
{
ResolveUrlMethodName = "Href"
};
host.GeneratedClassContext = new GeneratedClassContext(
GeneratedClassContext.DefaultExecuteMethodName,
GeneratedClassContext.DefaultWriteMethodName,
GeneratedClassContext.DefaultWriteLiteralMethodName,
"WriteTo",
"WriteLiteralTo",
"Template",
"DefineSection",
"Instrumentation.BeginContext",
"Instrumentation.EndContext",
new GeneratedTagHelperContext());
if (hostConfig != null)
{
host = hostConfig(host);

View File

@ -137,10 +137,9 @@ namespace Microsoft.AspNet.Razor.Test.Parser.Html
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace))),
Factory.Markup(" ~/Foo/Bar")
.WithEditorHints(EditorHints.VirtualPath)
.With(new LiteralAttributeChunkGenerator(
new LocationTagged<string>(" ", 13, 0, 13),
new LocationTagged<SpanChunkGenerator>(new ResolveUrlChunkGenerator(), 14, 0, 14))),
new LocationTagged<string>("~/Foo/Bar", 14, 0, 14))),
Factory.Markup("'").With(SpanChunkGenerator.Null)),
Factory.Markup(" />").Accepts(AcceptedCharacters.None))));
}
@ -181,33 +180,6 @@ namespace Microsoft.AspNet.Razor.Test.Parser.Html
Factory.Markup(" />"))));
}
[Fact]
public void ConditionalAttributeCollapserDoesNotRemoveUrlAttributeValues()
{
// Act
var results = ParseDocument("<a href='~/Foo/Bar' />");
var rewritingContext = new RewritingContext(results.Document, new ErrorSink());
new ConditionalAttributeCollapser(new HtmlMarkupParser().BuildSpan).Rewrite(rewritingContext);
new MarkupCollapser(new HtmlMarkupParser().BuildSpan).Rewrite(rewritingContext);
var rewritten = rewritingContext.SyntaxTree;
// Assert
Assert.Equal(0, results.ParserErrors.Count());
EvaluateParseTree(rewritten,
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<a"),
new MarkupBlock(new AttributeBlockChunkGenerator(name: "href", prefix: new LocationTagged<string>(" href='", 2, 0, 2), suffix: new LocationTagged<string>("'", 18, 0, 18)),
Factory.Markup(" href='").With(SpanChunkGenerator.Null),
Factory.Markup("~/Foo/Bar")
.WithEditorHints(EditorHints.VirtualPath)
.With(new LiteralAttributeChunkGenerator(
new LocationTagged<string>(string.Empty, 9, 0, 9),
new LocationTagged<SpanChunkGenerator>(new ResolveUrlChunkGenerator(), 9, 0, 9))),
Factory.Markup("'").With(SpanChunkGenerator.Null)),
Factory.Markup(" />"))));
}
[Fact]
public void ConditionalAttributeCollapserDoesNotRewriteEscapedTransitions()
{

View File

@ -1,293 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.Editor;
using Microsoft.AspNet.Razor.Parser;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Test.Framework;
using Microsoft.AspNet.Razor.Text;
using Xunit;
namespace Microsoft.AspNet.Razor.Test.Parser.Html
{
public class HtmlUrlAttributeTest : CsHtmlMarkupParserTestBase
{
[Fact]
public void SimpleUrlInAttributeInMarkupBlock()
{
ParseBlockTest("<a href='~/Foo/Bar/Baz' />",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<a"),
new MarkupBlock(new AttributeBlockChunkGenerator("href", new LocationTagged<string>(" href='", 2, 0, 2), new LocationTagged<string>("'", 22, 0, 22)),
Factory.Markup(" href='").With(SpanChunkGenerator.Null),
Factory.Markup("~/Foo/Bar/Baz")
.WithEditorHints(EditorHints.VirtualPath)
.With(new LiteralAttributeChunkGenerator(
new LocationTagged<string>(string.Empty, 9, 0, 9),
new LocationTagged<SpanChunkGenerator>(new ResolveUrlChunkGenerator(), 9, 0, 9))),
Factory.Markup("'").With(SpanChunkGenerator.Null)),
Factory.Markup(" />").Accepts(AcceptedCharacters.None))));
}
[Fact]
public void SimpleUrlInAttributeInMarkupDocument()
{
ParseDocumentTest("<a href='~/Foo/Bar/Baz' />",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<a"),
new MarkupBlock(new AttributeBlockChunkGenerator("href", new LocationTagged<string>(" href='", 2, 0, 2), new LocationTagged<string>("'", 22, 0, 22)),
Factory.Markup(" href='").With(SpanChunkGenerator.Null),
Factory.Markup("~/Foo/Bar/Baz")
.WithEditorHints(EditorHints.VirtualPath)
.With(new LiteralAttributeChunkGenerator(
new LocationTagged<string>(string.Empty, 9, 0, 9),
new LocationTagged<SpanChunkGenerator>(new ResolveUrlChunkGenerator(), 9, 0, 9))),
Factory.Markup("'").With(SpanChunkGenerator.Null)),
Factory.Markup(" />"))));
}
[Fact]
public void SimpleUrlInAttributeInMarkupSection()
{
ParseDocumentTest("@section Foo { <a href='~/Foo/Bar/Baz' /> }",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionChunkGenerator("Foo"),
Factory.CodeTransition(),
Factory.MetaCode("section Foo {")
.AutoCompleteWith(null, atEndOfSpan: true)
.Accepts(AcceptedCharacters.Any),
new MarkupBlock(
Factory.Markup(" "),
new MarkupTagBlock(
Factory.Markup("<a"),
new MarkupBlock(new AttributeBlockChunkGenerator("href", new LocationTagged<string>(" href='", 17, 0, 17), new LocationTagged<string>("'", 37, 0, 37)),
Factory.Markup(" href='").With(SpanChunkGenerator.Null),
Factory.Markup("~/Foo/Bar/Baz")
.WithEditorHints(EditorHints.VirtualPath)
.With(new LiteralAttributeChunkGenerator(
new LocationTagged<string>(string.Empty, 24, 0, 24),
new LocationTagged<SpanChunkGenerator>(new ResolveUrlChunkGenerator(), 24, 0, 24))),
Factory.Markup("'").With(SpanChunkGenerator.Null)),
Factory.Markup(" />")),
Factory.Markup(" ")
),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void UrlWithExpressionsInAttributeInMarkupBlock()
{
ParseBlockTest("<a href='~/Foo/@id/Baz' />",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<a"),
new MarkupBlock(new AttributeBlockChunkGenerator("href", new LocationTagged<string>(" href='", 2, 0, 2), new LocationTagged<string>("'", 22, 0, 22)),
Factory.Markup(" href='").With(SpanChunkGenerator.Null),
Factory.Markup("~/Foo/")
.WithEditorHints(EditorHints.VirtualPath)
.With(new LiteralAttributeChunkGenerator(
new LocationTagged<string>(string.Empty, 9, 0, 9),
new LocationTagged<SpanChunkGenerator>(new ResolveUrlChunkGenerator(), 9, 0, 9))),
new MarkupBlock(new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 15, 0, 15), 15, 0, 15),
new ExpressionBlock(
Factory.CodeTransition().Accepts(AcceptedCharacters.None),
Factory.Code("id")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace))),
Factory.Markup("/Baz")
.With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 18, 0, 18), new LocationTagged<string>("/Baz", 18, 0, 18))),
Factory.Markup("'").With(SpanChunkGenerator.Null)),
Factory.Markup(" />").Accepts(AcceptedCharacters.None))));
}
[Fact]
public void UrlWithExpressionsInAttributeInMarkupDocument()
{
ParseDocumentTest("<a href='~/Foo/@id/Baz' />",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<a"),
new MarkupBlock(new AttributeBlockChunkGenerator("href", new LocationTagged<string>(" href='", 2, 0, 2), new LocationTagged<string>("'", 22, 0, 22)),
Factory.Markup(" href='").With(SpanChunkGenerator.Null),
Factory.Markup("~/Foo/")
.WithEditorHints(EditorHints.VirtualPath)
.With(new LiteralAttributeChunkGenerator(
new LocationTagged<string>(string.Empty, 9, 0, 9),
new LocationTagged<SpanChunkGenerator>(new ResolveUrlChunkGenerator(), 9, 0, 9))),
new MarkupBlock(new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 15, 0, 15), 15, 0, 15),
new ExpressionBlock(
Factory.CodeTransition().Accepts(AcceptedCharacters.None),
Factory.Code("id")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace))),
Factory.Markup("/Baz")
.With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 18, 0, 18), new LocationTagged<string>("/Baz", 18, 0, 18))),
Factory.Markup("'").With(SpanChunkGenerator.Null)),
Factory.Markup(" />"))));
}
[Fact]
public void UrlWithExpressionsInAttributeInMarkupSection()
{
ParseDocumentTest("@section Foo { <a href='~/Foo/@id/Baz' /> }",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionChunkGenerator("Foo"),
Factory.CodeTransition(),
Factory.MetaCode("section Foo {")
.AutoCompleteWith(null, atEndOfSpan: true),
new MarkupBlock(
Factory.Markup(" "),
new MarkupTagBlock(
Factory.Markup("<a"),
new MarkupBlock(new AttributeBlockChunkGenerator("href", new LocationTagged<string>(" href='", 17, 0, 17), new LocationTagged<string>("'", 37, 0, 37)),
Factory.Markup(" href='").With(SpanChunkGenerator.Null),
Factory.Markup("~/Foo/")
.WithEditorHints(EditorHints.VirtualPath)
.With(new LiteralAttributeChunkGenerator(
new LocationTagged<string>(string.Empty, 24, 0, 24),
new LocationTagged<SpanChunkGenerator>(new ResolveUrlChunkGenerator(), 24, 0, 24))),
new MarkupBlock(new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 30, 0, 30), 30, 0, 30),
new ExpressionBlock(
Factory.CodeTransition().Accepts(AcceptedCharacters.None),
Factory.Code("id")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace))),
Factory.Markup("/Baz")
.With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 33, 0, 33), new LocationTagged<string>("/Baz", 33, 0, 33))),
Factory.Markup("'").With(SpanChunkGenerator.Null)),
Factory.Markup(" />")),
Factory.Markup(" ")
),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void UrlWithComplexCharactersInAttributeInMarkupBlock()
{
ParseBlockTest("<a href='~/Foo+Bar:Baz(Biz),Boz' />",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<a"),
new MarkupBlock(new AttributeBlockChunkGenerator("href", new LocationTagged<string>(" href='", 2, 0, 2), new LocationTagged<string>("'", 31, 0, 31)),
Factory.Markup(" href='").With(SpanChunkGenerator.Null),
Factory.Markup("~/Foo+Bar:Baz(Biz),Boz")
.WithEditorHints(EditorHints.VirtualPath)
.With(new LiteralAttributeChunkGenerator(
new LocationTagged<string>(string.Empty, 9, 0, 9),
new LocationTagged<SpanChunkGenerator>(new ResolveUrlChunkGenerator(), 9, 0, 9))),
Factory.Markup("'").With(SpanChunkGenerator.Null)),
Factory.Markup(" />").Accepts(AcceptedCharacters.None))));
}
[Fact]
public void UrlWithComplexCharactersInAttributeInMarkupDocument()
{
ParseDocumentTest("<a href='~/Foo+Bar:Baz(Biz),Boz' />",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<a"),
new MarkupBlock(new AttributeBlockChunkGenerator("href", new LocationTagged<string>(" href='", 2, 0, 2), new LocationTagged<string>("'", 31, 0, 31)),
Factory.Markup(" href='").With(SpanChunkGenerator.Null),
Factory.Markup("~/Foo+Bar:Baz(Biz),Boz")
.WithEditorHints(EditorHints.VirtualPath)
.With(new LiteralAttributeChunkGenerator(
new LocationTagged<string>(string.Empty, 9, 0, 9),
new LocationTagged<SpanChunkGenerator>(new ResolveUrlChunkGenerator(), 9, 0, 9))),
Factory.Markup("'").With(SpanChunkGenerator.Null)),
Factory.Markup(" />"))));
}
[Fact]
public void UrlInUnquotedAttributeValueInMarkupBlock()
{
ParseBlockTest("<a href=~/Foo+Bar:Baz(Biz),Boz/@id/Boz />",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<a"),
new MarkupBlock(new AttributeBlockChunkGenerator("href", new LocationTagged<string>(" href=", 2, 0, 2), new LocationTagged<string>(string.Empty, 38, 0, 38)),
Factory.Markup(" href=").With(SpanChunkGenerator.Null),
Factory.Markup("~/Foo+Bar:Baz(Biz),Boz/")
.WithEditorHints(EditorHints.VirtualPath)
.With(new LiteralAttributeChunkGenerator(
new LocationTagged<string>(string.Empty, 8, 0, 8),
new LocationTagged<SpanChunkGenerator>(new ResolveUrlChunkGenerator(), 8, 0, 8))),
new MarkupBlock(new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 31, 0, 31), 31, 0, 31),
new ExpressionBlock(
Factory.CodeTransition()
.Accepts(AcceptedCharacters.None),
Factory.Code("id")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace))),
Factory.Markup("/Boz").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 34, 0, 34), new LocationTagged<string>("/Boz", 34, 0, 34)))),
Factory.Markup(" />").Accepts(AcceptedCharacters.None))));
}
[Fact]
public void UrlInUnquotedAttributeValueInMarkupDocument()
{
ParseDocumentTest("<a href=~/Foo+Bar:Baz(Biz),Boz/@id/Boz />",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<a"),
new MarkupBlock(new AttributeBlockChunkGenerator("href", new LocationTagged<string>(" href=", 2, 0, 2), new LocationTagged<string>(string.Empty, 38, 0, 38)),
Factory.Markup(" href=").With(SpanChunkGenerator.Null),
Factory.Markup("~/Foo+Bar:Baz(Biz),Boz/")
.WithEditorHints(EditorHints.VirtualPath)
.With(new LiteralAttributeChunkGenerator(
new LocationTagged<string>(string.Empty, 8, 0, 8),
new LocationTagged<SpanChunkGenerator>(new ResolveUrlChunkGenerator(), 8, 0, 8))),
new MarkupBlock(new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 31, 0, 31), 31, 0, 31),
new ExpressionBlock(
Factory.CodeTransition()
.Accepts(AcceptedCharacters.None),
Factory.Code("id")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace))),
Factory.Markup("/Boz").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 34, 0, 34), new LocationTagged<string>("/Boz", 34, 0, 34)))),
Factory.Markup(" />"))));
}
[Fact]
public void UrlInUnquotedAttributeValueInMarkupSection()
{
ParseDocumentTest("@section Foo { <a href=~/Foo+Bar:Baz(Biz),Boz/@id/Boz /> }",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionChunkGenerator("Foo"),
Factory.CodeTransition(),
Factory.MetaCode("section Foo {")
.AutoCompleteWith(null, atEndOfSpan: true),
new MarkupBlock(
Factory.Markup(" "),
new MarkupTagBlock(
Factory.Markup("<a"),
new MarkupBlock(new AttributeBlockChunkGenerator("href", new LocationTagged<string>(" href=", 17, 0, 17), new LocationTagged<string>(string.Empty, 53, 0, 53)),
Factory.Markup(" href=").With(SpanChunkGenerator.Null),
Factory.Markup("~/Foo+Bar:Baz(Biz),Boz/")
.WithEditorHints(EditorHints.VirtualPath)
.With(new LiteralAttributeChunkGenerator(
new LocationTagged<string>(string.Empty, 23, 0, 23),
new LocationTagged<SpanChunkGenerator>(new ResolveUrlChunkGenerator(), 23, 0, 23))),
new MarkupBlock(new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 46, 0, 46), 46, 0, 46),
new ExpressionBlock(
Factory.CodeTransition()
.Accepts(AcceptedCharacters.None),
Factory.Code("id")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace))),
Factory.Markup("/Boz").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 49, 0, 49), new LocationTagged<string>("/Boz", 49, 0, 49)))),
Factory.Markup(" />")),
Factory.Markup(" ")
),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
}
}

View File

@ -73,12 +73,8 @@ WriteTo(__razor_attribute_value_writer, cls);
}
), 256), false));
Instrumentation.BeginContext(282, 11, true);
WriteLiteral(" />\r\n <a");
Instrumentation.EndContext();
WriteAttribute("href", Tuple.Create(" href=\"", 293), Tuple.Create("\"", 305), Tuple.Create(Tuple.Create("", 300), Tuple.Create<System.Object, System.Int32>(Href("~/Foo"), 300), false));
Instrumentation.BeginContext(306, 16, true);
WriteLiteral(" />\r\n <script");
Instrumentation.BeginContext(282, 40, true);
WriteLiteral(" />\r\n <a href=\"~/Foo\" />\r\n <script");
Instrumentation.EndContext();
WriteAttribute("src", Tuple.Create(" src=\"", 322), Tuple.Create("\"", 373),
Tuple.Create(Tuple.Create("", 328), Tuple.Create<System.Object, System.Int32>(Url.Content("~/Scripts/jquery-1.6.2.min.js"), 328), false));

View File

@ -14,12 +14,8 @@ namespace TestOutput
#pragma warning disable 1998
public override async Task ExecuteAsync()
{
Instrumentation.BeginContext(0, 16, true);
WriteLiteral("<!-- \" -->\r\n<img");
Instrumentation.EndContext();
WriteAttribute("src", Tuple.Create(" src=\"", 16), Tuple.Create("\"", 41), Tuple.Create(Tuple.Create("", 22), Tuple.Create<System.Object, System.Int32>(Href("~/images/submit.png"), 22), false));
Instrumentation.BeginContext(42, 3, true);
WriteLiteral(" />");
Instrumentation.BeginContext(0, 45, true);
WriteLiteral("<!-- \" -->\r\n<img src=\"~/images/submit.png\" />");
Instrumentation.EndContext();
}
#pragma warning restore 1998

View File

@ -14,12 +14,8 @@ namespace TestOutput
#pragma warning disable 1998
public override async Task ExecuteAsync()
{
Instrumentation.BeginContext(0, 16, true);
WriteLiteral("<!-- \' -->\r\n<img");
Instrumentation.EndContext();
WriteAttribute("src", Tuple.Create(" src=\"", 16), Tuple.Create("\"", 41), Tuple.Create(Tuple.Create("", 22), Tuple.Create<System.Object, System.Int32>(Href("~/images/submit.png"), 22), false));
Instrumentation.BeginContext(42, 3, true);
WriteLiteral(" />");
Instrumentation.BeginContext(0, 45, true);
WriteLiteral("<!-- \' -->\r\n<img src=\"~/images/submit.png\" />");
Instrumentation.EndContext();
}
#pragma warning restore 1998

View File

@ -1,133 +0,0 @@
#pragma checksum "ResolveUrl.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "ee17a91893cee3c8590202192de89abe32776cc2"
namespace TestOutput
{
using System;
using System.Threading.Tasks;
public class ResolveUrl
{
#line hidden
public ResolveUrl()
{
}
#pragma warning disable 1998
public override async Task ExecuteAsync()
{
Instrumentation.BeginContext(0, 2, true);
WriteLiteral("<a");
Instrumentation.EndContext();
WriteAttribute("href", Tuple.Create(" href=\"", 2), Tuple.Create("\"", 14), Tuple.Create(Tuple.Create("", 9), Tuple.Create<System.Object, System.Int32>(Href("~/Foo"), 9), false));
Instrumentation.BeginContext(15, 12, true);
WriteLiteral(">Foo</a>\r\n<a");
Instrumentation.EndContext();
WriteAttribute("href", Tuple.Create(" href=\"", 27), Tuple.Create("\"", 56), Tuple.Create(Tuple.Create("", 34), Tuple.Create<System.Object, System.Int32>(Href("~/Products/"), 34), false),
Tuple.Create(Tuple.Create("", 45), Tuple.Create<System.Object, System.Int32>(product.id, 45), false));
Instrumentation.BeginContext(57, 1, true);
WriteLiteral(">");
Instrumentation.EndContext();
Instrumentation.BeginContext(59, 12, false);
#line 2 "ResolveUrl.cshtml"
Write(product.Name);
#line default
#line hidden
Instrumentation.EndContext();
Instrumentation.BeginContext(71, 8, true);
WriteLiteral("</a>\r\n<a");
Instrumentation.EndContext();
WriteAttribute("href", Tuple.Create(" href=\"", 79), Tuple.Create("\"", 115), Tuple.Create(Tuple.Create("", 86), Tuple.Create<System.Object, System.Int32>(Href("~/Products/"), 86), false),
Tuple.Create(Tuple.Create("", 97), Tuple.Create<System.Object, System.Int32>(product.id, 97), false), Tuple.Create(Tuple.Create("", 108), Tuple.Create("/Detail", 108), true));
Instrumentation.BeginContext(116, 16, true);
WriteLiteral(">Details</a>\r\n<a");
Instrumentation.EndContext();
WriteAttribute("href", Tuple.Create(" href=\"", 132), Tuple.Create("\"", 187), Tuple.Create(Tuple.Create("", 139), Tuple.Create<System.Object, System.Int32>(Href("~/A+Really(Crazy),Url.Is:This/"), 139), false),
Tuple.Create(Tuple.Create("", 169), Tuple.Create<System.Object, System.Int32>(product.id, 169), false), Tuple.Create(Tuple.Create("", 180), Tuple.Create("/Detail", 180), true));
Instrumentation.BeginContext(188, 19, true);
WriteLiteral(">Crazy Url!</a>\r\n\r\n");
Instrumentation.EndContext();
#line 6 "ResolveUrl.cshtml"
#line default
#line hidden
Instrumentation.BeginContext(221, 12, true);
WriteLiteral("\r\n <a");
Instrumentation.EndContext();
WriteAttribute("href", Tuple.Create(" href=\"", 233), Tuple.Create("\"", 245), Tuple.Create(Tuple.Create("", 240), Tuple.Create<System.Object, System.Int32>(Href("~/Foo"), 240), false));
Instrumentation.BeginContext(246, 20, true);
WriteLiteral(">Foo</a>\r\n <a");
Instrumentation.EndContext();
WriteAttribute("href", Tuple.Create(" href=\"", 266), Tuple.Create("\"", 295), Tuple.Create(Tuple.Create("", 273), Tuple.Create<System.Object, System.Int32>(Href("~/Products/"), 273), false),
Tuple.Create(Tuple.Create("", 284), Tuple.Create<System.Object, System.Int32>(product.id, 284), false));
Instrumentation.BeginContext(296, 1, true);
WriteLiteral(">");
Instrumentation.EndContext();
Instrumentation.BeginContext(298, 12, false);
#line 9 "ResolveUrl.cshtml"
Write(product.Name);
#line default
#line hidden
Instrumentation.EndContext();
Instrumentation.BeginContext(310, 16, true);
WriteLiteral("</a>\r\n <a");
Instrumentation.EndContext();
WriteAttribute("href", Tuple.Create(" href=\"", 326), Tuple.Create("\"", 362), Tuple.Create(Tuple.Create("", 333), Tuple.Create<System.Object, System.Int32>(Href("~/Products/"), 333), false),
Tuple.Create(Tuple.Create("", 344), Tuple.Create<System.Object, System.Int32>(product.id, 344), false), Tuple.Create(Tuple.Create("", 355), Tuple.Create("/Detail", 355), true));
Instrumentation.BeginContext(363, 24, true);
WriteLiteral(">Details</a>\r\n <a");
Instrumentation.EndContext();
WriteAttribute("href", Tuple.Create(" href=\"", 387), Tuple.Create("\"", 442), Tuple.Create(Tuple.Create("", 394), Tuple.Create<System.Object, System.Int32>(Href("~/A+Really(Crazy),Url.Is:This/"), 394), false),
Tuple.Create(Tuple.Create("", 424), Tuple.Create<System.Object, System.Int32>(product.id, 424), false), Tuple.Create(Tuple.Create("", 435), Tuple.Create("/Detail", 435), true));
Instrumentation.BeginContext(443, 23, true);
WriteLiteral(">Crazy Url!</a>\r\n \r\n");
Instrumentation.EndContext();
#line 13 "ResolveUrl.cshtml"
#line default
#line hidden
Instrumentation.BeginContext(474, 4, true);
WriteLiteral("\r\n\r\n");
Instrumentation.EndContext();
DefineSection("Foo", async(__razor_template_writer) => {
Instrumentation.BeginContext(492, 8, true);
WriteLiteralTo(__razor_template_writer, "\r\n <a");
Instrumentation.EndContext();
WriteAttributeTo(__razor_template_writer, "href", Tuple.Create(" href=\"", 500), Tuple.Create("\"", 512), Tuple.Create(Tuple.Create("", 507), Tuple.Create<System.Object, System.Int32>(Href("~/Foo"), 507), false));
Instrumentation.BeginContext(513, 16, true);
WriteLiteralTo(__razor_template_writer, ">Foo</a>\r\n <a");
Instrumentation.EndContext();
WriteAttributeTo(__razor_template_writer, "href", Tuple.Create(" href=\"", 529), Tuple.Create("\"", 558), Tuple.Create(Tuple.Create("", 536), Tuple.Create<System.Object, System.Int32>(Href("~/Products/"), 536), false),
Tuple.Create(Tuple.Create("", 547), Tuple.Create<System.Object, System.Int32>(product.id, 547), false));
Instrumentation.BeginContext(559, 1, true);
WriteLiteralTo(__razor_template_writer, ">");
Instrumentation.EndContext();
Instrumentation.BeginContext(561, 12, false);
#line 17 "ResolveUrl.cshtml"
WriteTo(__razor_template_writer, product.Name);
#line default
#line hidden
Instrumentation.EndContext();
Instrumentation.BeginContext(573, 12, true);
WriteLiteralTo(__razor_template_writer, "</a>\r\n <a");
Instrumentation.EndContext();
WriteAttributeTo(__razor_template_writer, "href", Tuple.Create(" href=\"", 585), Tuple.Create("\"", 621), Tuple.Create(Tuple.Create("", 592), Tuple.Create<System.Object, System.Int32>(Href("~/Products/"), 592), false),
Tuple.Create(Tuple.Create("", 603), Tuple.Create<System.Object, System.Int32>(product.id, 603), false), Tuple.Create(Tuple.Create("", 614), Tuple.Create("/Detail", 614), true));
Instrumentation.BeginContext(622, 20, true);
WriteLiteralTo(__razor_template_writer, ">Details</a>\r\n <a");
Instrumentation.EndContext();
WriteAttributeTo(__razor_template_writer, "href", Tuple.Create(" href=\"", 642), Tuple.Create("\"", 697), Tuple.Create(Tuple.Create("", 649), Tuple.Create<System.Object, System.Int32>(Href("~/A+Really(Crazy),Url.Is:This/"), 649), false),
Tuple.Create(Tuple.Create("", 679), Tuple.Create<System.Object, System.Int32>(product.id, 679), false), Tuple.Create(Tuple.Create("", 690), Tuple.Create("/Detail", 690), true));
Instrumentation.BeginContext(698, 17, true);
WriteLiteralTo(__razor_template_writer, ">Crazy Url!</a>\r\n");
Instrumentation.EndContext();
}
);
}
#pragma warning restore 1998
}
}

View File

@ -1,20 +0,0 @@
<a href="~/Foo">Foo</a>
<a href="~/Products/@product.id">@product.Name</a>
<a href="~/Products/@product.id/Detail">Details</a>
<a href="~/A+Really(Crazy),Url.Is:This/@product.id/Detail">Crazy Url!</a>
@{
<text>
<a href="~/Foo">Foo</a>
<a href="~/Products/@product.id">@product.Name</a>
<a href="~/Products/@product.id/Detail">Details</a>
<a href="~/A+Really(Crazy),Url.Is:This/@product.id/Detail">Crazy Url!</a>
</text>
}
@section Foo {
<a href="~/Foo">Foo</a>
<a href="~/Products/@product.id">@product.Name</a>
<a href="~/Products/@product.id/Detail">Details</a>
<a href="~/A+Really(Crazy),Url.Is:This/@product.id/Detail">Crazy Url!</a>
}