Add model for differentiating design time and runtime parsing.
- If needed, a phase/feature can always retrieve the syntax tree to lookup whether the parse tree was made in a "design time" fashion. - Future DesignTime / Runtime specific bits will be added to their corresponding `AddRuntimeDefaults`/`AddDesignTimeDefaults` methods.
This commit is contained in:
parent
6ae3feff29
commit
61b2b0d4e7
|
|
@ -0,0 +1,19 @@
|
||||||
|
// 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.AspNetCore.Razor.Evolution
|
||||||
|
{
|
||||||
|
internal class DefaultRazorDesignTimeCSharpLoweringPhase : RazorEnginePhaseBase, IRazorCSharpLoweringPhase
|
||||||
|
{
|
||||||
|
protected override void ExecuteCore(RazorCodeDocument codeDocument)
|
||||||
|
{
|
||||||
|
var irDocument = codeDocument.GetIRDocument();
|
||||||
|
ThrowForMissingDependency(irDocument);
|
||||||
|
|
||||||
|
var syntaxTree = codeDocument.GetSyntaxTree();
|
||||||
|
ThrowForMissingDependency(syntaxTree);
|
||||||
|
|
||||||
|
// Render design time CSharp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Razor.Evolution
|
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
|
|
@ -17,6 +18,8 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
|
|
||||||
public IList<IRazorEnginePhase> Phases { get; }
|
public IList<IRazorEnginePhase> Phases { get; }
|
||||||
|
|
||||||
|
public bool DesignTime { get; set; }
|
||||||
|
|
||||||
public RazorEngine Build()
|
public RazorEngine Build()
|
||||||
{
|
{
|
||||||
var features = new IRazorEngineFeature[Features.Count];
|
var features = new IRazorEngineFeature[Features.Count];
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Razor.Evolution
|
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
{
|
{
|
||||||
internal class DefaultRazorCSharpLoweringPhase : RazorEnginePhaseBase, IRazorCSharpLoweringPhase
|
internal class DefaultRazorRuntimeCSharpLoweringPhase : RazorEnginePhaseBase, IRazorCSharpLoweringPhase
|
||||||
{
|
{
|
||||||
protected override void ExecuteCore(RazorCodeDocument codeDocument)
|
protected override void ExecuteCore(RazorCodeDocument codeDocument)
|
||||||
{
|
{
|
||||||
|
|
@ -11,6 +11,8 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
|
|
||||||
IList<IRazorEnginePhase> Phases { get; }
|
IList<IRazorEnginePhase> Phases { get; }
|
||||||
|
|
||||||
|
bool DesignTime { get; set; }
|
||||||
|
|
||||||
RazorEngine Build();
|
RazorEngine Build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,24 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
{
|
{
|
||||||
var builder = new DefaultRazorEngineBuilder();
|
var builder = new DefaultRazorEngineBuilder();
|
||||||
AddDefaults(builder);
|
AddDefaults(builder);
|
||||||
|
AddRuntimeDefaults(builder);
|
||||||
|
configure?.Invoke(builder);
|
||||||
|
return builder.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RazorEngine CreateDesignTime()
|
||||||
|
{
|
||||||
|
return CreateDesignTime(configure: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RazorEngine CreateDesignTime(Action<IRazorEngineBuilder> configure)
|
||||||
|
{
|
||||||
|
var builder = new DefaultRazorEngineBuilder()
|
||||||
|
{
|
||||||
|
DesignTime = true,
|
||||||
|
};
|
||||||
|
AddDefaults(builder);
|
||||||
|
AddDesignTimeDefaults(builder);
|
||||||
configure?.Invoke(builder);
|
configure?.Invoke(builder);
|
||||||
return builder.Build();
|
return builder.Build();
|
||||||
}
|
}
|
||||||
|
|
@ -34,7 +52,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
builder.Phases.Add(new DefaultRazorSyntaxTreePhase());
|
builder.Phases.Add(new DefaultRazorSyntaxTreePhase());
|
||||||
builder.Phases.Add(new DefaultRazorIRLoweringPhase());
|
builder.Phases.Add(new DefaultRazorIRLoweringPhase());
|
||||||
builder.Phases.Add(new DefaultRazorIRPhase());
|
builder.Phases.Add(new DefaultRazorIRPhase());
|
||||||
builder.Phases.Add(new DefaultRazorCSharpLoweringPhase());
|
|
||||||
|
|
||||||
// Syntax Tree passes
|
// Syntax Tree passes
|
||||||
builder.Features.Add(new DefaultDirectiveSyntaxTreePass());
|
builder.Features.Add(new DefaultDirectiveSyntaxTreePass());
|
||||||
|
|
@ -45,10 +62,34 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
builder.Features.Add(new DefaultDirectiveIRPass());
|
builder.Features.Add(new DefaultDirectiveIRPass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static void AddRuntimeDefaults(IRazorEngineBuilder builder)
|
||||||
|
{
|
||||||
|
builder.Phases.Add(new DefaultRazorRuntimeCSharpLoweringPhase());
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void AddDesignTimeDefaults(IRazorEngineBuilder builder)
|
||||||
|
{
|
||||||
|
builder.Phases.Add(new DefaultRazorDesignTimeCSharpLoweringPhase());
|
||||||
|
|
||||||
|
builder.Features.Add(new ConfigureDesignTimeOptions());
|
||||||
|
}
|
||||||
|
|
||||||
public abstract IReadOnlyList<IRazorEngineFeature> Features { get; }
|
public abstract IReadOnlyList<IRazorEngineFeature> Features { get; }
|
||||||
|
|
||||||
public abstract IReadOnlyList<IRazorEnginePhase> Phases { get; }
|
public abstract IReadOnlyList<IRazorEnginePhase> Phases { get; }
|
||||||
|
|
||||||
public abstract void Process(RazorCodeDocument document);
|
public abstract void Process(RazorCodeDocument document);
|
||||||
|
|
||||||
|
internal class ConfigureDesignTimeOptions : IRazorConfigureParserFeature
|
||||||
|
{
|
||||||
|
public RazorEngine Engine { get; set; }
|
||||||
|
|
||||||
|
public int Order { get; set; }
|
||||||
|
|
||||||
|
public void Configure(RazorParserOptions options)
|
||||||
|
{
|
||||||
|
options.DesignTimeMode = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,13 @@ using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Razor.Evolution
|
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
{
|
{
|
||||||
public class DefaultRazorCSharpLoweringPhaseTest
|
public class DefaultRazorRuntimeCSharpLoweringPhaseTest
|
||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Execute_ThrowsForMissingDependency()
|
public void Execute_ThrowsForMissingDependency()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var phase = new DefaultRazorCSharpLoweringPhase();
|
var phase = new DefaultRazorRuntimeCSharpLoweringPhase();
|
||||||
|
|
||||||
var engine = RazorEngine.CreateEmpty(b => b.Phases.Add(phase));
|
var engine = RazorEngine.CreateEmpty(b => b.Phases.Add(phase));
|
||||||
|
|
||||||
|
|
@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
ExceptionAssert.Throws<InvalidOperationException>(
|
ExceptionAssert.Throws<InvalidOperationException>(
|
||||||
() => phase.Execute(codeDocument),
|
() => phase.Execute(codeDocument),
|
||||||
$"The '{nameof(DefaultRazorCSharpLoweringPhase)}' phase requires a '{nameof(DocumentIRNode)}' " +
|
$"The '{nameof(DefaultRazorRuntimeCSharpLoweringPhase)}' phase requires a '{nameof(DocumentIRNode)}' " +
|
||||||
$"provided by the '{nameof(RazorCodeDocument)}'.");
|
$"provided by the '{nameof(RazorCodeDocument)}'.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
public class RazorEngineTest
|
public class RazorEngineTest
|
||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Create_NoArg_CreatesDefaultEngine()
|
public void Create_NoArg_CreatesDefaultRuntimeEngine()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -19,12 +19,25 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsType<DefaultRazorEngine>(engine);
|
Assert.IsType<DefaultRazorEngine>(engine);
|
||||||
AssertDefaultFeatures(engine.Features);
|
AssertDefaultRuntimeFeatures(engine.Features);
|
||||||
AssertDefaultPhases(engine.Phases);
|
AssertDefaultRuntimePhases(engine.Phases);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Create_Null_CreatesDefaultEngine()
|
public void CreateDesignTime_NoArg_CreatesDefaultDesignTimeEngine()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
// Act
|
||||||
|
var engine = RazorEngine.CreateDesignTime();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsType<DefaultRazorEngine>(engine);
|
||||||
|
AssertDefaultDesignTimeFeatures(engine.Features);
|
||||||
|
AssertDefaultDesignTimePhases(engine.Phases);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Create_Null_CreatesDefaultRuntimeEngine()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -32,8 +45,21 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsType<DefaultRazorEngine>(engine);
|
Assert.IsType<DefaultRazorEngine>(engine);
|
||||||
AssertDefaultFeatures(engine.Features);
|
AssertDefaultRuntimeFeatures(engine.Features);
|
||||||
AssertDefaultPhases(engine.Phases);
|
AssertDefaultRuntimePhases(engine.Phases);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CreateDesignTime_Null_CreatesDefaultDesignTimeEngine()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
// Act
|
||||||
|
var engine = RazorEngine.CreateDesignTime(configure: null);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsType<DefaultRazorEngine>(engine);
|
||||||
|
AssertDefaultDesignTimeFeatures(engine.Features);
|
||||||
|
AssertDefaultDesignTimePhases(engine.Phases);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -71,7 +97,42 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
p => Assert.Same(phases[1], p));
|
p => Assert.Same(phases[1], p));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AssertDefaultFeatures(IEnumerable<IRazorEngineFeature> features)
|
[Fact]
|
||||||
|
public void CreateDesignTime_Lambda_AddsFeaturesAndPhases()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
IRazorEngineFeature[] features = null;
|
||||||
|
IRazorEnginePhase[] phases = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var engine = RazorEngine.CreateDesignTime(builder =>
|
||||||
|
{
|
||||||
|
builder.Features.Clear();
|
||||||
|
builder.Phases.Clear();
|
||||||
|
|
||||||
|
builder.Features.Add(Mock.Of<IRazorEngineFeature>());
|
||||||
|
builder.Features.Add(Mock.Of<IRazorEngineFeature>());
|
||||||
|
|
||||||
|
builder.Phases.Add(Mock.Of<IRazorEnginePhase>());
|
||||||
|
builder.Phases.Add(Mock.Of<IRazorEnginePhase>());
|
||||||
|
|
||||||
|
features = builder.Features.ToArray();
|
||||||
|
phases = builder.Phases.ToArray();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Collection(
|
||||||
|
engine.Features,
|
||||||
|
f => Assert.Same(features[0], f),
|
||||||
|
f => Assert.Same(features[1], f));
|
||||||
|
|
||||||
|
Assert.Collection(
|
||||||
|
engine.Phases,
|
||||||
|
p => Assert.Same(phases[0], p),
|
||||||
|
p => Assert.Same(phases[1], p));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AssertDefaultRuntimeFeatures(IEnumerable<IRazorEngineFeature> features)
|
||||||
{
|
{
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
features,
|
features,
|
||||||
|
|
@ -81,7 +142,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
feature => Assert.IsType<DefaultDirectiveIRPass>(feature));
|
feature => Assert.IsType<DefaultDirectiveIRPass>(feature));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AssertDefaultPhases(IReadOnlyList<IRazorEnginePhase> phases)
|
private static void AssertDefaultRuntimePhases(IReadOnlyList<IRazorEnginePhase> phases)
|
||||||
{
|
{
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
phases,
|
phases,
|
||||||
|
|
@ -89,7 +150,29 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
phase => Assert.IsType<DefaultRazorSyntaxTreePhase>(phase),
|
phase => Assert.IsType<DefaultRazorSyntaxTreePhase>(phase),
|
||||||
phase => Assert.IsType<DefaultRazorIRLoweringPhase>(phase),
|
phase => Assert.IsType<DefaultRazorIRLoweringPhase>(phase),
|
||||||
phase => Assert.IsType<DefaultRazorIRPhase>(phase),
|
phase => Assert.IsType<DefaultRazorIRPhase>(phase),
|
||||||
phase => Assert.IsType<DefaultRazorCSharpLoweringPhase>(phase));
|
phase => Assert.IsType<DefaultRazorRuntimeCSharpLoweringPhase>(phase));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AssertDefaultDesignTimeFeatures(IEnumerable<IRazorEngineFeature> features)
|
||||||
|
{
|
||||||
|
Assert.Collection(
|
||||||
|
features,
|
||||||
|
feature => Assert.IsType<DefaultDirectiveSyntaxTreePass>(feature),
|
||||||
|
feature => Assert.IsType<TagHelperBinderSyntaxTreePass>(feature),
|
||||||
|
feature => Assert.IsType<HtmlNodeOptimizationPass>(feature),
|
||||||
|
feature => Assert.IsType<DefaultDirectiveIRPass>(feature),
|
||||||
|
feature => Assert.IsType<RazorEngine.ConfigureDesignTimeOptions>(feature));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AssertDefaultDesignTimePhases(IReadOnlyList<IRazorEnginePhase> phases)
|
||||||
|
{
|
||||||
|
Assert.Collection(
|
||||||
|
phases,
|
||||||
|
phase => Assert.IsType<DefaultRazorParsingPhase>(phase),
|
||||||
|
phase => Assert.IsType<DefaultRazorSyntaxTreePhase>(phase),
|
||||||
|
phase => Assert.IsType<DefaultRazorIRLoweringPhase>(phase),
|
||||||
|
phase => Assert.IsType<DefaultRazorIRPhase>(phase),
|
||||||
|
phase => Assert.IsType<DefaultRazorDesignTimeCSharpLoweringPhase>(phase));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue