Update to use Razor parser to parse page directive
This commit is contained in:
parent
17a74a4c2d
commit
20c04d099e
|
|
@ -3,12 +3,29 @@
|
|||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Extensions;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||
{
|
||||
public static class PageDirectiveFeature
|
||||
{
|
||||
private static readonly RazorEngine PageDirectiveEngine = RazorEngine.Create(builder =>
|
||||
{
|
||||
for (var i = builder.Phases.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var phase = builder.Phases[i];
|
||||
builder.Phases.RemoveAt(i);
|
||||
if (phase is IRazorDocumentClassifierPhase)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RazorExtensions.Register(builder);
|
||||
builder.Features.Add(new PageDirectiveParserOptionsFeature());
|
||||
});
|
||||
|
||||
public static bool TryGetPageDirective(RazorProjectItem projectItem, out string template)
|
||||
{
|
||||
if (projectItem == null)
|
||||
|
|
@ -16,7 +33,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
throw new ArgumentNullException(nameof(projectItem));
|
||||
}
|
||||
|
||||
return TryGetPageDirective(projectItem.Read, out template);
|
||||
var sourceDocument = RazorSourceDocument.ReadFrom(projectItem);
|
||||
return TryGetPageDirective(sourceDocument, out template);
|
||||
}
|
||||
|
||||
public static bool TryGetPageDirective(Func<Stream> streamFactory, out string template)
|
||||
|
|
@ -26,38 +44,36 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
throw new ArgumentNullException(nameof(streamFactory));
|
||||
}
|
||||
|
||||
const string PageDirective = "@page";
|
||||
|
||||
string content;
|
||||
using (var streamReader = new StreamReader(streamFactory()))
|
||||
using (var stream = streamFactory())
|
||||
{
|
||||
do
|
||||
{
|
||||
content = streamReader.ReadLine();
|
||||
var sourceDocument = RazorSourceDocument.ReadFrom(stream, fileName: "Parse.cshtml");
|
||||
return TryGetPageDirective(sourceDocument, out template);
|
||||
}
|
||||
}
|
||||
|
||||
} while (content != null && string.IsNullOrWhiteSpace(content));
|
||||
content = content?.Trim();
|
||||
private static bool TryGetPageDirective(RazorSourceDocument sourceDocument, out string template)
|
||||
{
|
||||
var codeDocument = RazorCodeDocument.Create(sourceDocument);
|
||||
PageDirectiveEngine.Process(codeDocument);
|
||||
|
||||
if (PageDirective.TryGetPageDirective(codeDocument.GetIRDocument(), out var pageDirective))
|
||||
{
|
||||
template = pageDirective.RouteTemplate;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (content == null || !content.StartsWith(PageDirective, StringComparison.Ordinal))
|
||||
{
|
||||
template = null;
|
||||
return false;
|
||||
}
|
||||
template = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
template = content.Substring(PageDirective.Length, content.Length - PageDirective.Length).TrimStart();
|
||||
private class PageDirectiveParserOptionsFeature : RazorEngineFeatureBase, IRazorParserOptionsFeature
|
||||
{
|
||||
public int Order { get; }
|
||||
|
||||
if (template.StartsWith("\"") && template.EndsWith("\""))
|
||||
public void Configure(RazorParserOptionsBuilder options)
|
||||
{
|
||||
template = template.Substring(1, template.Length - 2);
|
||||
options.ParseOnlyLeadingDirectives = true;
|
||||
}
|
||||
// If it's not in quotes it's not our template
|
||||
else
|
||||
{
|
||||
template = string.Empty;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,18 +48,6 @@ The rest of the thing");
|
|||
Assert.Null(template);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_MultipleQuotes()
|
||||
{
|
||||
// Arrange
|
||||
string template;
|
||||
var projectItem = new TestRazorProjectItem(@"@page """"template""""");
|
||||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Equal(@"""template""", template);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(@"""Some/Path/{value}")]
|
||||
[InlineData(@"Some/Path/{value}""")]
|
||||
|
|
@ -71,10 +59,9 @@ The rest of the thing");
|
|||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Equal(string.Empty, template);
|
||||
Assert.Null(template);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void TryGetPageDirective_NoQuotesAroundPath_IsNotTemplate()
|
||||
{
|
||||
|
|
@ -84,7 +71,7 @@ The rest of the thing");
|
|||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Equal(string.Empty, template);
|
||||
Assert.Null(template);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -126,7 +113,7 @@ The rest of the thing");
|
|||
Assert.Equal("Some/Path/{value}", template);
|
||||
}
|
||||
|
||||
[Fact(Skip = "Re-evaluate this scenario after we use Razor to parse this stuff")]
|
||||
[Fact]
|
||||
public void TryGetPageDirective_JunkBeforeNewline()
|
||||
{
|
||||
// Arrange
|
||||
|
|
@ -136,7 +123,7 @@ a new line");
|
|||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Empty(template);
|
||||
Assert.Equal("Some/Path/{value}", template);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -148,7 +135,7 @@ a new line");
|
|||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Empty(template);
|
||||
Assert.Null(template);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -161,7 +148,7 @@ Non-path things");
|
|||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(projectItem, out template));
|
||||
Assert.Empty(template);
|
||||
Assert.Null(template);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -236,21 +223,9 @@ Nobody will use it");
|
|||
}
|
||||
}
|
||||
|
||||
public override string Path
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
public override string Path => "Test.cshtml";
|
||||
|
||||
public override string PhysicalPath
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
public override string PhysicalPath => null;
|
||||
|
||||
public override Stream Read()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue