diff --git a/src/Microsoft.AspNetCore.Razor.Language/DefaultRazorCodeGenerationOptionsBuilder.cs b/src/Microsoft.AspNetCore.Razor.Language/DefaultRazorCodeGenerationOptionsBuilder.cs index 8d6ec2f97c..79acdf8d44 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/DefaultRazorCodeGenerationOptionsBuilder.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/DefaultRazorCodeGenerationOptionsBuilder.cs @@ -5,7 +5,12 @@ namespace Microsoft.AspNetCore.Razor.Language { internal class DefaultRazorCodeGenerationOptionsBuilder : RazorCodeGenerationOptionsBuilder { - public override bool DesignTime { get; set; } + public DefaultRazorCodeGenerationOptionsBuilder(bool designTime) + { + DesignTime = designTime; + } + + public override bool DesignTime { get; } public override int IndentSize { get; set; } = 4; diff --git a/src/Microsoft.AspNetCore.Razor.Language/DefaultRazorCodeGenerationOptionsFeature.cs b/src/Microsoft.AspNetCore.Razor.Language/DefaultRazorCodeGenerationOptionsFeature.cs new file mode 100644 index 0000000000..70ca502788 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/DefaultRazorCodeGenerationOptionsFeature.cs @@ -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 DefaultRazorCodeGenerationOptionsFeature : RazorEngineFeatureBase, IRazorCodeGenerationOptionsFeature + { + private readonly bool _designTime; + private IConfigureRazorCodeGenerationOptionsFeature[] _configureOptions; + + public DefaultRazorCodeGenerationOptionsFeature(bool designTime) + { + _designTime = designTime; + } + + protected override void OnInitialized() + { + _configureOptions = Engine.Features.OfType().ToArray(); + } + + public RazorCodeGenerationOptions GetOptions() + { + var builder = new DefaultRazorCodeGenerationOptionsBuilder(_designTime); + for (var i = 0; i < _configureOptions.Length; i++) + { + _configureOptions[i].Configure(builder); + } + + var options = builder.Build(); + + return options; + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/DefaultRazorIntermediateNodeLoweringPhase.cs b/src/Microsoft.AspNetCore.Razor.Language/DefaultRazorIntermediateNodeLoweringPhase.cs index 7a5b9e34a8..76fa627415 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/DefaultRazorIntermediateNodeLoweringPhase.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/DefaultRazorIntermediateNodeLoweringPhase.cs @@ -13,11 +13,11 @@ namespace Microsoft.AspNetCore.Razor.Language { internal class DefaultRazorIntermediateNodeLoweringPhase : RazorEnginePhaseBase, IRazorIntermediateNodeLoweringPhase { - private IRazorCodeGenerationOptionsFeature[] _optionsCallbacks; + private IRazorCodeGenerationOptionsFeature _optionsFeature; protected override void OnIntialized() { - _optionsCallbacks = Engine.Features.OfType().OrderBy(f => f.Order).ToArray(); + _optionsFeature = GetRequiredFeature(); } protected override void ExecuteCore(RazorCodeDocument codeDocument) @@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.Razor.Language var document = new DocumentIntermediateNode(); var builder = IntermediateNodeBuilder.Create(document); - document.Options = CreateCodeGenerationOptions(); + document.Options = _optionsFeature.GetOptions(); var namespaces = new Dictionary(StringComparer.Ordinal); @@ -146,17 +146,6 @@ namespace Microsoft.AspNetCore.Razor.Language } } - private RazorCodeGenerationOptions CreateCodeGenerationOptions() - { - var builder = new DefaultRazorCodeGenerationOptionsBuilder(); - for (var i = 0; i < _optionsCallbacks.Length; i++) - { - _optionsCallbacks[i].Configure(builder); - } - - return builder.Build(); - } - private class LoweringVisitor : ParserVisitor { protected readonly IntermediateNodeBuilder _builder; diff --git a/src/Microsoft.AspNetCore.Razor.Language/IConfigureRazorCodeGenerationOptionsFeature.cs b/src/Microsoft.AspNetCore.Razor.Language/IConfigureRazorCodeGenerationOptionsFeature.cs new file mode 100644 index 0000000000..e1f50c0fab --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/IConfigureRazorCodeGenerationOptionsFeature.cs @@ -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 IConfigureRazorCodeGenerationOptionsFeature : IRazorEngineFeature + { + int Order { get; } + + void Configure(RazorCodeGenerationOptionsBuilder options); + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/IRazorCodeGenerationOptionsFeature.cs b/src/Microsoft.AspNetCore.Razor.Language/IRazorCodeGenerationOptionsFeature.cs index 4181a9e6d9..dc97b6326c 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/IRazorCodeGenerationOptionsFeature.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/IRazorCodeGenerationOptionsFeature.cs @@ -5,8 +5,6 @@ namespace Microsoft.AspNetCore.Razor.Language { public interface IRazorCodeGenerationOptionsFeature : IRazorEngineFeature { - int Order { get; } - - void Configure(RazorCodeGenerationOptionsBuilder options); + RazorCodeGenerationOptions GetOptions(); } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/RazorCodeGenerationOptions.cs b/src/Microsoft.AspNetCore.Razor.Language/RazorCodeGenerationOptions.cs index 21568d2bbf..6e73d6a004 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/RazorCodeGenerationOptions.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorCodeGenerationOptions.cs @@ -1,15 +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. +using System; + namespace Microsoft.AspNetCore.Razor.Language { public abstract class RazorCodeGenerationOptions { - public static RazorCodeGenerationOptions Create(bool indentWithTabs, int indentSize, bool designTime, bool suppressChecksum) - { - return new DefaultRazorCodeGenerationOptions(indentWithTabs, indentSize, designTime, suppressChecksum); - } - public static RazorCodeGenerationOptions CreateDefault() { return new DefaultRazorCodeGenerationOptions(indentWithTabs: false, indentSize: 4, designTime: false, suppressChecksum: false); @@ -20,6 +17,34 @@ namespace Microsoft.AspNetCore.Razor.Language return new DefaultRazorCodeGenerationOptions(indentWithTabs: false, indentSize: 4, designTime: true, suppressChecksum: false); } + public static RazorCodeGenerationOptions Create(Action configure) + { + if (configure == null) + { + throw new ArgumentNullException(nameof(configure)); + } + + var builder = new DefaultRazorCodeGenerationOptionsBuilder(designTime: false); + configure(builder); + var options = builder.Build(); + + return options; + } + + public static RazorCodeGenerationOptions CreateDesignTime(Action configure) + { + if (configure == null) + { + throw new ArgumentNullException(nameof(configure)); + } + + var builder = new DefaultRazorCodeGenerationOptionsBuilder(designTime: true); + configure(builder); + var options = builder.Build(); + + return options; + } + public abstract bool DesignTime { get; } public abstract bool IndentWithTabs { get; } diff --git a/src/Microsoft.AspNetCore.Razor.Language/RazorCodeGenerationOptionsBuilder.cs b/src/Microsoft.AspNetCore.Razor.Language/RazorCodeGenerationOptionsBuilder.cs index 024cd7a169..3b24c23bfe 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/RazorCodeGenerationOptionsBuilder.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorCodeGenerationOptionsBuilder.cs @@ -5,7 +5,7 @@ namespace Microsoft.AspNetCore.Razor.Language { public abstract class RazorCodeGenerationOptionsBuilder { - public abstract bool DesignTime { get; set; } + public abstract bool DesignTime { get; } public abstract int IndentSize { get; set; } diff --git a/src/Microsoft.AspNetCore.Razor.Language/RazorEngine.cs b/src/Microsoft.AspNetCore.Razor.Language/RazorEngine.cs index 2c0d4d28a4..7fec6786d7 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/RazorEngine.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorEngine.cs @@ -103,6 +103,7 @@ namespace Microsoft.AspNetCore.Razor.Language { // Configure options builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false)); + builder.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false)); // Intermediate Node Passes builder.Features.Add(new PreallocatedTagHelperAttributeOptimizationPass()); @@ -116,7 +117,8 @@ namespace Microsoft.AspNetCore.Razor.Language { // Configure options builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: true)); - builder.Features.Add(new DesignTimeOptionsFeature()); + builder.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: true)); + builder.Features.Add(new SuppressChecksumOptionsFeature()); // Intermediate Node Passes builder.Features.Add(new DesignTimeDirectivePass()); diff --git a/src/Microsoft.AspNetCore.Razor.Language/DesignTimeOptionsFeature.cs b/src/Microsoft.AspNetCore.Razor.Language/SuppressChecksumOptionsFeature.cs similarity index 79% rename from src/Microsoft.AspNetCore.Razor.Language/DesignTimeOptionsFeature.cs rename to src/Microsoft.AspNetCore.Razor.Language/SuppressChecksumOptionsFeature.cs index 2c989d8aba..81e9f2a02d 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/DesignTimeOptionsFeature.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/SuppressChecksumOptionsFeature.cs @@ -5,7 +5,7 @@ using System; namespace Microsoft.AspNetCore.Razor.Language { - internal class DesignTimeOptionsFeature : RazorEngineFeatureBase, IRazorCodeGenerationOptionsFeature + internal class SuppressChecksumOptionsFeature : RazorEngineFeatureBase, IConfigureRazorCodeGenerationOptionsFeature { public int Order { get; set; } @@ -16,7 +16,6 @@ namespace Microsoft.AspNetCore.Razor.Language throw new ArgumentNullException(nameof(options)); } - options.DesignTime = true; options.SuppressChecksum = true; } } diff --git a/src/RazorPageGenerator/Program.cs b/src/RazorPageGenerator/Program.cs index 131f662265..336aa88dcf 100644 --- a/src/RazorPageGenerator/Program.cs +++ b/src/RazorPageGenerator/Program.cs @@ -108,7 +108,7 @@ namespace RazorPageGenerator }; } - private class SuppressChecksumOptionsFeature : RazorEngineFeatureBase, IRazorCodeGenerationOptionsFeature + private class SuppressChecksumOptionsFeature : RazorEngineFeatureBase, IConfigureRazorCodeGenerationOptionsFeature { public int Order { get; set; } diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultDocumentWriterTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultDocumentWriterTest.cs index 88d3b8ea01..74d48a1f8d 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultDocumentWriterTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultDocumentWriterTest.cs @@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration var document = new DocumentIntermediateNode(); var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var optionsBuilder = new DefaultRazorCodeGenerationOptionsBuilder() + var optionsBuilder = new DefaultRazorCodeGenerationOptionsBuilder(designTime: false) { SuppressChecksum = true }; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorIntermediateNodeLoweringPhaseIntegrationTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorIntermediateNodeLoweringPhaseIntegrationTest.cs index deb9218c3e..6f6e084869 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorIntermediateNodeLoweringPhaseIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorIntermediateNodeLoweringPhaseIntegrationTest.cs @@ -36,22 +36,24 @@ namespace Microsoft.AspNetCore.Razor.Language // Arrange var codeDocument = TestRazorCodeDocument.CreateEmpty(); - var callback = new Mock(); + var callback = new Mock(); callback .Setup(c => c.Configure(It.IsAny())) .Callback(o => { - o.DesignTime = true; o.IndentSize = 17; o.IndentWithTabs = true; o.SuppressChecksum = true; }); // Act - var documentNode = Lower(codeDocument, builder: b => - { - b.Features.Add(callback.Object); - }); + var documentNode = Lower( + codeDocument, + builder: b => + { + b.Features.Add(callback.Object); + }, + designTime: true); // Assert Assert.NotNull(documentNode.Options); @@ -431,18 +433,21 @@ namespace Microsoft.AspNetCore.Razor.Language private DocumentIntermediateNode Lower( RazorCodeDocument codeDocument, Action builder = null, - IEnumerable tagHelpers = null) + IEnumerable tagHelpers = null, + bool designTime = false) { tagHelpers = tagHelpers ?? new TagHelperDescriptor[0]; - var engine = RazorEngine.Create(b => + Action configureEngine = b => { builder?.Invoke(b); FunctionsDirective.Register(b); SectionDirective.Register(b); b.AddTagHelpers(tagHelpers); - }); + }; + + var engine = designTime ? RazorEngine.CreateDesignTime(configureEngine) : RazorEngine.Create(configureEngine); for (var i = 0; i < engine.Phases.Count; i++) { diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorIntermediateNodeLoweringPhaseTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorIntermediateNodeLoweringPhaseTest.cs index 356049a240..1288b1b127 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorIntermediateNodeLoweringPhaseTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorIntermediateNodeLoweringPhaseTest.cs @@ -26,6 +26,7 @@ namespace Microsoft.AspNetCore.Razor.Language var engine = RazorEngine.CreateEmpty(b => { b.Phases.Add(phase); + b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false)); b.AddDirective(directive); }); var options = RazorParserOptions.Create(builder => builder.Directives.Add(directive)); @@ -60,6 +61,7 @@ namespace Microsoft.AspNetCore.Razor.Language var engine = RazorEngine.CreateEmpty(b => { b.Phases.Add(phase); + b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false)); b.AddDirective(directive); }); var options = RazorParserOptions.Create(builder => builder.Directives.Add(directive)); @@ -94,6 +96,7 @@ namespace Microsoft.AspNetCore.Razor.Language var engine = RazorEngine.CreateEmpty(b => { b.Phases.Add(phase); + b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false)); b.AddDirective(directive); }); var options = RazorParserOptions.Create(builder => builder.Directives.Add(directive)); @@ -124,6 +127,7 @@ namespace Microsoft.AspNetCore.Razor.Language var engine = RazorEngine.CreateEmpty(b => { b.Phases.Add(phase); + b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false)); b.AddDirective(codeBlockDirective); b.AddDirective(razorBlockDirective); }); @@ -158,6 +162,7 @@ namespace Microsoft.AspNetCore.Razor.Language var engine = RazorEngine.CreateEmpty(b => { b.Phases.Add(phase); + b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false)); b.AddDirective(directive); }); var options = RazorParserOptions.Create(builder => builder.Directives.Add(directive)); @@ -187,6 +192,7 @@ namespace Microsoft.AspNetCore.Razor.Language var engine = RazorEngine.CreateEmpty(b => { b.Phases.Add(phase); + b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false)); b.AddDirective(directive); }); var options = RazorParserOptions.Create(builder => builder.Directives.Add(directive)); @@ -213,7 +219,11 @@ namespace Microsoft.AspNetCore.Razor.Language // Arrange var phase = new DefaultRazorIntermediateNodeLoweringPhase(); - var engine = RazorEngine.CreateEmpty(b => b.Phases.Add(phase)); + var engine = RazorEngine.CreateEmpty(b => + { + b.Phases.Add(phase); + b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false)); + }); var codeDocument = TestRazorCodeDocument.CreateEmpty(); @@ -229,7 +239,11 @@ namespace Microsoft.AspNetCore.Razor.Language { // Arrange var phase = new DefaultRazorIntermediateNodeLoweringPhase(); - var engine = RazorEngine.CreateEmpty(b => b.Phases.Add(phase)); + var engine = RazorEngine.CreateEmpty(b => + { + b.Phases.Add(phase); + b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false)); + }); var codeDocument = TestRazorCodeDocument.Create("

b.Phases.Add(phase)); + var engine = RazorEngine.CreateEmpty(b => + { + b.Phases.Add(phase); + b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false)); + }); var codeDocument = TestRazorCodeDocument.CreateEmpty(); codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source)); diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/RazorEngineTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/RazorEngineTest.cs index a7c1dbe787..57639292ea 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/RazorEngineTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/RazorEngineTest.cs @@ -161,6 +161,7 @@ namespace Microsoft.AspNetCore.Razor.Language feature => Assert.IsType(feature), feature => Assert.IsType(feature), feature => Assert.IsType(feature), + feature => Assert.IsType(feature), feature => Assert.IsType(feature)); } @@ -202,7 +203,8 @@ namespace Microsoft.AspNetCore.Razor.Language feature => Assert.IsType(feature), feature => Assert.IsType(feature), feature => Assert.IsType(feature), - feature => Assert.IsType(feature), + feature => Assert.IsType(feature), + feature => Assert.IsType(feature), feature => Assert.IsType(feature)); }