Make `RazorParserOptions.DesignTime` getter only.

- Renamed `IRazorParserOptionsFeature` to `IConfigureRazorParserOptionsFeature`, the original interface was re-purposed to get the options rather than configure them.
- This involved re-designing how we set design time on the `RazorParserOptions` object. The indicator of `DesignTime` is now configured at the RazorEngine level via a parser options provider feature.
- Moved options construction from the phase into an `IRazorParserOptionsFeature` type.

#1510
This commit is contained in:
N. Taylor Mullen 2017-07-06 12:14:45 -07:00
parent 17f97397e6
commit 87a5435036
11 changed files with 83 additions and 39 deletions

View File

@ -6,13 +6,13 @@ using System.Collections.Generic;
namespace Microsoft.AspNetCore.Razor.Language namespace Microsoft.AspNetCore.Razor.Language
{ {
internal class DefaultRazorDirectiveFeature : RazorEngineFeatureBase, IRazorDirectiveFeature, IRazorParserOptionsFeature internal class DefaultRazorDirectiveFeature : RazorEngineFeatureBase, IRazorDirectiveFeature, IConfigureRazorParserOptionsFeature
{ {
public ICollection<DirectiveDescriptor> Directives { get; } = new List<DirectiveDescriptor>(); public ICollection<DirectiveDescriptor> Directives { get; } = new List<DirectiveDescriptor>();
public int Order => 100; public int Order => 100;
void IRazorParserOptionsFeature.Configure(RazorParserOptionsBuilder options) void IConfigureRazorParserOptionsFeature.Configure(RazorParserOptionsBuilder options)
{ {
if (options == null) if (options == null)
{ {

View File

@ -8,7 +8,12 @@ namespace Microsoft.AspNetCore.Razor.Language
{ {
internal class DefaultRazorParserOptionsBuilder : RazorParserOptionsBuilder internal class DefaultRazorParserOptionsBuilder : RazorParserOptionsBuilder
{ {
public override bool DesignTime { get; set; } public DefaultRazorParserOptionsBuilder(bool designTime)
{
DesignTime = designTime;
}
public override bool DesignTime { get; }
public override ICollection<DirectiveDescriptor> Directives { get; } = new List<DirectiveDescriptor>(); public override ICollection<DirectiveDescriptor> Directives { get; } = new List<DirectiveDescriptor>();

View File

@ -0,0 +1,36 @@
// 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 System.Linq;
namespace Microsoft.AspNetCore.Razor.Language
{
internal class DefaultRazorParserOptionsFeature : RazorEngineFeatureBase, IRazorParserOptionsFeature
{
private readonly bool _designTime;
private IConfigureRazorParserOptionsFeature[] _configureOptions;
public DefaultRazorParserOptionsFeature(bool designTime)
{
_designTime = designTime;
}
protected override void OnInitialized()
{
_configureOptions = Engine.Features.OfType<IConfigureRazorParserOptionsFeature>().ToArray();
}
public RazorParserOptions GetOptions()
{
var builder = new DefaultRazorParserOptionsBuilder(_designTime);
for (var i = 0; i < _configureOptions.Length; i++)
{
_configureOptions[i].Configure(builder);
}
var options = builder.Build();
return options;
}
}
}

View File

@ -1,29 +1,20 @@
// 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.Linq;
namespace Microsoft.AspNetCore.Razor.Language namespace Microsoft.AspNetCore.Razor.Language
{ {
internal class DefaultRazorParsingPhase : RazorEnginePhaseBase, IRazorParsingPhase internal class DefaultRazorParsingPhase : RazorEnginePhaseBase, IRazorParsingPhase
{ {
private IRazorParserOptionsFeature[] _parserOptionsCallbacks; private IRazorParserOptionsFeature _optionsFeature;
protected override void OnIntialized() protected override void OnIntialized()
{ {
_parserOptionsCallbacks = Engine.Features.OfType<IRazorParserOptionsFeature>().ToArray(); _optionsFeature = GetRequiredFeature<IRazorParserOptionsFeature>();
} }
protected override void ExecuteCore(RazorCodeDocument codeDocument) protected override void ExecuteCore(RazorCodeDocument codeDocument)
{ {
var builder = new DefaultRazorParserOptionsBuilder(); var options = _optionsFeature.GetOptions();
for (var i = 0; i < _parserOptionsCallbacks.Length; i++)
{
_parserOptionsCallbacks[i].Configure(builder);
}
var options = builder.Build();
var syntaxTree = RazorSyntaxTree.Parse(codeDocument.Source, options); var syntaxTree = RazorSyntaxTree.Parse(codeDocument.Source, options);
codeDocument.SetSyntaxTree(syntaxTree); codeDocument.SetSyntaxTree(syntaxTree);

View File

@ -5,20 +5,10 @@ using System;
namespace Microsoft.AspNetCore.Razor.Language namespace Microsoft.AspNetCore.Razor.Language
{ {
internal class DesignTimeOptionsFeature : RazorEngineFeatureBase, IRazorParserOptionsFeature, IRazorCodeGenerationOptionsFeature internal class DesignTimeOptionsFeature : RazorEngineFeatureBase, IRazorCodeGenerationOptionsFeature
{ {
public int Order { get; set; } public int Order { get; set; }
public void Configure(RazorParserOptionsBuilder options)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
options.DesignTime = true;
}
public void Configure(RazorCodeGenerationOptionsBuilder options) public void Configure(RazorCodeGenerationOptionsBuilder options)
{ {
if (options == null) if (options == null)

View File

@ -0,0 +1,12 @@
// 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.Language
{
public interface IConfigureRazorParserOptionsFeature : IRazorEngineFeature
{
int Order { get; }
void Configure(RazorParserOptionsBuilder options);
}
}

View File

@ -5,8 +5,6 @@ namespace Microsoft.AspNetCore.Razor.Language
{ {
public interface IRazorParserOptionsFeature : IRazorEngineFeature public interface IRazorParserOptionsFeature : IRazorEngineFeature
{ {
int Order { get; } RazorParserOptions GetOptions();
void Configure(RazorParserOptionsBuilder options);
} }
} }

View File

@ -4,7 +4,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Extensions; using Microsoft.AspNetCore.Razor.Language.Extensions;
namespace Microsoft.AspNetCore.Razor.Language namespace Microsoft.AspNetCore.Razor.Language
@ -105,6 +104,9 @@ namespace Microsoft.AspNetCore.Razor.Language
internal static void AddRuntimeDefaults(IRazorEngineBuilder builder) internal static void AddRuntimeDefaults(IRazorEngineBuilder builder)
{ {
// Configure options
builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false));
// Intermediate Node Passes // Intermediate Node Passes
builder.Features.Add(new PreallocatedTagHelperAttributeOptimizationPass()); builder.Features.Add(new PreallocatedTagHelperAttributeOptimizationPass());
@ -116,6 +118,7 @@ namespace Microsoft.AspNetCore.Razor.Language
internal static void AddDesignTimeDefaults(IRazorEngineBuilder builder) internal static void AddDesignTimeDefaults(IRazorEngineBuilder builder)
{ {
// Configure options // Configure options
builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: true));
builder.Features.Add(new DesignTimeOptionsFeature()); builder.Features.Add(new DesignTimeOptionsFeature());
// Intermediate Node Passes // Intermediate Node Passes

View File

@ -7,7 +7,7 @@ namespace Microsoft.AspNetCore.Razor.Language
{ {
public abstract class RazorParserOptionsBuilder public abstract class RazorParserOptionsBuilder
{ {
public abstract bool DesignTime { get; set; } public abstract bool DesignTime { get; }
public abstract ICollection<DirectiveDescriptor> Directives { get; } public abstract ICollection<DirectiveDescriptor> Directives { get; }

View File

@ -12,7 +12,11 @@ namespace Microsoft.AspNetCore.Razor.Language
{ {
// Arrange // Arrange
var phase = new DefaultRazorParsingPhase(); var phase = new DefaultRazorParsingPhase();
var engine = RazorEngine.CreateEmpty(b => b.Phases.Add(phase)); var engine = RazorEngine.CreateEmpty(builder =>
{
builder.Phases.Add(phase);
builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false));
});
var codeDocument = TestRazorCodeDocument.CreateEmpty(); var codeDocument = TestRazorCodeDocument.CreateEmpty();
@ -28,10 +32,11 @@ namespace Microsoft.AspNetCore.Razor.Language
{ {
// Arrange // Arrange
var phase = new DefaultRazorParsingPhase(); var phase = new DefaultRazorParsingPhase();
var engine = RazorEngine.CreateEmpty((b) => var engine = RazorEngine.CreateEmpty((builder) =>
{ {
b.Phases.Add(phase); builder.Phases.Add(phase);
b.Features.Add(new MyParserOptionsFeature()); builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false));
builder.Features.Add(new MyParserOptionsFeature());
}); });
var codeDocument = TestRazorCodeDocument.CreateEmpty(); var codeDocument = TestRazorCodeDocument.CreateEmpty();
@ -50,10 +55,12 @@ namespace Microsoft.AspNetCore.Razor.Language
{ {
// Arrange // Arrange
var phase = new DefaultRazorParsingPhase(); var phase = new DefaultRazorParsingPhase();
var engine = RazorEngine.CreateEmpty((b) => var engine = RazorEngine.CreateEmpty((builder) =>
{ {
b.Phases.Add(phase); builder.Phases.Add(phase);
b.Features.Add(new MyParserOptionsFeature()); builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false));
builder.Features.Add(new MyParserOptionsFeature());
}); });
var imports = new[] var imports = new[]
@ -74,7 +81,7 @@ namespace Microsoft.AspNetCore.Razor.Language
t => { Assert.Same(t.Source, imports[1]); Assert.Equal("test", Assert.Single(t.Options.Directives).Directive); }); t => { Assert.Same(t.Source, imports[1]); Assert.Equal("test", Assert.Single(t.Options.Directives).Directive); });
} }
private class MyParserOptionsFeature : RazorEngineFeatureBase, IRazorParserOptionsFeature private class MyParserOptionsFeature : RazorEngineFeatureBase, IConfigureRazorParserOptionsFeature
{ {
public int Order { get; } public int Order { get; }

View File

@ -160,6 +160,7 @@ namespace Microsoft.AspNetCore.Razor.Language
feature => Assert.IsType<DirectiveRemovalOptimizationPass>(feature), feature => Assert.IsType<DirectiveRemovalOptimizationPass>(feature),
feature => Assert.IsType<DefaultTagHelperOptimizationPass>(feature), feature => Assert.IsType<DefaultTagHelperOptimizationPass>(feature),
feature => Assert.IsType<DefaultDocumentClassifierPassFeature>(feature), feature => Assert.IsType<DefaultDocumentClassifierPassFeature>(feature),
feature => Assert.IsType<DefaultRazorParserOptionsFeature>(feature),
feature => Assert.IsType<PreallocatedTagHelperAttributeOptimizationPass>(feature)); feature => Assert.IsType<PreallocatedTagHelperAttributeOptimizationPass>(feature));
} }
@ -200,6 +201,7 @@ namespace Microsoft.AspNetCore.Razor.Language
feature => Assert.IsType<DirectiveRemovalOptimizationPass>(feature), feature => Assert.IsType<DirectiveRemovalOptimizationPass>(feature),
feature => Assert.IsType<DefaultTagHelperOptimizationPass>(feature), feature => Assert.IsType<DefaultTagHelperOptimizationPass>(feature),
feature => Assert.IsType<DefaultDocumentClassifierPassFeature>(feature), feature => Assert.IsType<DefaultDocumentClassifierPassFeature>(feature),
feature => Assert.IsType<DefaultRazorParserOptionsFeature>(feature),
feature => Assert.IsType<DesignTimeOptionsFeature>(feature), feature => Assert.IsType<DesignTimeOptionsFeature>(feature),
feature => Assert.IsType<DesignTimeDirectivePass>(feature)); feature => Assert.IsType<DesignTimeDirectivePass>(feature));
} }