[Fixes #5844] Using ExtensionIRNode for Inject directive
This commit is contained in:
parent
acfad83aa6
commit
f7c2e5bffc
|
|
@ -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.
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Razor.Evolution.CodeGeneration;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Mvc.Razor.Host
|
||||||
|
{
|
||||||
|
public interface IInjectDirectiveTargetExtension : IRuntimeTargetExtension
|
||||||
|
{
|
||||||
|
void WriteInjectProperty(CSharpRenderingContext context, InjectDirectiveIRNode node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -49,14 +49,15 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
|
||||||
|
|
||||||
typeName = typeName.Replace("<TModel>", "<" + modelType + ">");
|
typeName = typeName.Replace("<TModel>", "<" + modelType + ">");
|
||||||
|
|
||||||
var member = new CSharpStatementIRNode()
|
var injectNode = new InjectDirectiveIRNode()
|
||||||
{
|
{
|
||||||
|
TypeName = typeName,
|
||||||
|
MemberName = memberName,
|
||||||
Source = directive.Source,
|
Source = directive.Source,
|
||||||
Content = $"[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]{Environment.NewLine}public {typeName} {memberName} {{ get; private set; }}",
|
|
||||||
Parent = visitor.Class,
|
Parent = visitor.Class,
|
||||||
};
|
};
|
||||||
|
|
||||||
visitor.Class.Children.Add(member);
|
visitor.Class.Children.Add(injectNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
// 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;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.AspNetCore.Razor.Evolution;
|
||||||
|
using Microsoft.AspNetCore.Razor.Evolution.CodeGeneration;
|
||||||
|
using Microsoft.AspNetCore.Razor.Evolution.Intermediate;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Mvc.Razor.Host
|
||||||
|
{
|
||||||
|
public class InjectDirectiveIRNode : ExtensionIRNode
|
||||||
|
{
|
||||||
|
public string TypeName { get; set; }
|
||||||
|
|
||||||
|
public string MemberName { get; set; }
|
||||||
|
|
||||||
|
public override IList<RazorIRNode> Children { get; } = new RazorIRNode[0];
|
||||||
|
|
||||||
|
public override RazorIRNode Parent { get; set; }
|
||||||
|
|
||||||
|
public override SourceSpan? Source { get; set; }
|
||||||
|
|
||||||
|
public override void Accept(RazorIRNodeVisitor visitor)
|
||||||
|
{
|
||||||
|
if (visitor == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(visitor));
|
||||||
|
}
|
||||||
|
|
||||||
|
AcceptExtensionNode<InjectDirectiveIRNode>(this, visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TResult Accept<TResult>(RazorIRNodeVisitor<TResult> visitor)
|
||||||
|
{
|
||||||
|
if (visitor == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(visitor));
|
||||||
|
}
|
||||||
|
|
||||||
|
return AcceptExtensionNode<InjectDirectiveIRNode, TResult>(this, visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteNode(RuntimeTarget target, CSharpRenderingContext context)
|
||||||
|
{
|
||||||
|
if (target == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
var extension = target.GetExtension<IInjectDirectiveTargetExtension>();
|
||||||
|
extension.WriteInjectProperty(context, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
// 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;
|
||||||
|
using Microsoft.AspNetCore.Razor.Evolution.CodeGeneration;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Mvc.Razor.Host
|
||||||
|
{
|
||||||
|
public class InjectDirectiveTargetExtension : IInjectDirectiveTargetExtension
|
||||||
|
{
|
||||||
|
private const string RazorInjectAttribute = "[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]";
|
||||||
|
|
||||||
|
public void WriteInjectProperty(CSharpRenderingContext context, InjectDirectiveIRNode node)
|
||||||
|
{
|
||||||
|
if (context == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
var property = $"public {node.TypeName} {node.MemberName} {{ get; private set; }}";
|
||||||
|
|
||||||
|
if (node.Source.HasValue)
|
||||||
|
{
|
||||||
|
using (context.Writer.BuildLinePragma(node.Source.Value))
|
||||||
|
{
|
||||||
|
context.Writer
|
||||||
|
.WriteLine(RazorInjectAttribute)
|
||||||
|
.WriteLine(property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.Writer
|
||||||
|
.WriteLine(RazorInjectAttribute)
|
||||||
|
.WriteLine(property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -184,6 +184,8 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
InjectDirective.Register(b);
|
InjectDirective.Register(b);
|
||||||
ModelDirective.Register(b);
|
ModelDirective.Register(b);
|
||||||
PageDirective.Register(b);
|
PageDirective.Register(b);
|
||||||
|
|
||||||
|
b.AddTargetExtension(new InjectDirectiveTargetExtension());
|
||||||
|
|
||||||
b.Features.Add(new ModelExpressionPass());
|
b.Features.Add(new ModelExpressionPass());
|
||||||
b.Features.Add(new PagesPropertyInjectionPass());
|
b.Features.Add(new PagesPropertyInjectionPass());
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
// 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;
|
||||||
|
using Microsoft.AspNetCore.Razor.Evolution;
|
||||||
|
using Microsoft.AspNetCore.Razor.Evolution.CodeGeneration;
|
||||||
|
using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Mvc.Razor.Host
|
||||||
|
{
|
||||||
|
public class InjectDirectiveTargetExtensionTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void InjectDirectiveTargetExtension_WritesProperty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var context = GetRenderingContext();
|
||||||
|
var target = new InjectDirectiveTargetExtension();
|
||||||
|
var node = new InjectDirectiveIRNode()
|
||||||
|
{
|
||||||
|
TypeName = "PropertyType",
|
||||||
|
MemberName = "PropertyName",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
target.WriteInjectProperty(context, node);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(
|
||||||
|
"[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine +
|
||||||
|
"public PropertyType PropertyName { get; private set; }" + Environment.NewLine,
|
||||||
|
context.Writer.Builder.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InjectDirectiveTargetExtension_WritesPropertyWithLinePragma_WhenSourceIsSet()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var context = GetRenderingContext();
|
||||||
|
var target = new InjectDirectiveTargetExtension();
|
||||||
|
var node = new InjectDirectiveIRNode()
|
||||||
|
{
|
||||||
|
TypeName = "PropertyType<ModelType>",
|
||||||
|
MemberName = "PropertyName",
|
||||||
|
Source = new SourceSpan(
|
||||||
|
filePath: "test-path",
|
||||||
|
absoluteIndex: 0,
|
||||||
|
lineIndex: 1,
|
||||||
|
characterIndex: 1,
|
||||||
|
length: 10)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
target.WriteInjectProperty(context, node);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(
|
||||||
|
"#line 2 \"test-path\"" + Environment.NewLine +
|
||||||
|
"[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine +
|
||||||
|
"public PropertyType<ModelType> PropertyName { get; private set; }" + Environment.NewLine + Environment.NewLine +
|
||||||
|
"#line default" + Environment.NewLine +
|
||||||
|
"#line hidden" + Environment.NewLine,
|
||||||
|
context.Writer.Builder.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private CSharpRenderingContext GetRenderingContext()
|
||||||
|
{
|
||||||
|
return new CSharpRenderingContext()
|
||||||
|
{
|
||||||
|
Writer = new CSharpCodeWriter()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
// 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.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.AspNetCore.Razor.Evolution;
|
using Microsoft.AspNetCore.Razor.Evolution;
|
||||||
|
|
@ -36,11 +35,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
|
||||||
Assert.NotNull(@class);
|
Assert.NotNull(@class);
|
||||||
Assert.Equal(2, @class.Children.Count);
|
Assert.Equal(2, @class.Children.Count);
|
||||||
|
|
||||||
var statement = Assert.IsType<CSharpStatementIRNode>(@class.Children[1]);
|
var node = Assert.IsType<InjectDirectiveIRNode>(@class.Children[1]);
|
||||||
Assert.Equal(
|
Assert.Equal("PropertyType", node.TypeName);
|
||||||
"[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine +
|
Assert.Equal("PropertyName", node.MemberName);
|
||||||
"public PropertyType PropertyName { get; private set; }",
|
|
||||||
statement.Content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -68,11 +65,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
|
||||||
Assert.NotNull(@class);
|
Assert.NotNull(@class);
|
||||||
Assert.Equal(2, @class.Children.Count);
|
Assert.Equal(2, @class.Children.Count);
|
||||||
|
|
||||||
var statement = Assert.IsType<CSharpStatementIRNode>(@class.Children[1]);
|
var node = Assert.IsType<InjectDirectiveIRNode>(@class.Children[1]);
|
||||||
Assert.Equal(
|
Assert.Equal("PropertyType2", node.TypeName);
|
||||||
"[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine +
|
Assert.Equal("PropertyName", node.MemberName);
|
||||||
"public PropertyType2 PropertyName { get; private set; }",
|
|
||||||
statement.Content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -99,11 +94,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
|
||||||
Assert.NotNull(@class);
|
Assert.NotNull(@class);
|
||||||
Assert.Equal(2, @class.Children.Count);
|
Assert.Equal(2, @class.Children.Count);
|
||||||
|
|
||||||
var statement = Assert.IsType<CSharpStatementIRNode>(@class.Children[1]);
|
var node = Assert.IsType<InjectDirectiveIRNode>(@class.Children[1]);
|
||||||
Assert.Equal(
|
Assert.Equal("PropertyType<dynamic>", node.TypeName);
|
||||||
"[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine +
|
Assert.Equal("PropertyName", node.MemberName);
|
||||||
"public PropertyType<dynamic> PropertyName { get; private set; }",
|
|
||||||
statement.Content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -131,11 +124,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
|
||||||
Assert.NotNull(@class);
|
Assert.NotNull(@class);
|
||||||
Assert.Equal(2, @class.Children.Count);
|
Assert.Equal(2, @class.Children.Count);
|
||||||
|
|
||||||
var statement = Assert.IsType<CSharpStatementIRNode>(@class.Children[1]);
|
var node = Assert.IsType<InjectDirectiveIRNode>(@class.Children[1]);
|
||||||
Assert.Equal(
|
Assert.Equal("PropertyType<ModelType>", node.TypeName);
|
||||||
"[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine +
|
Assert.Equal("PropertyName", node.MemberName);
|
||||||
"public PropertyType<ModelType> PropertyName { get; private set; }",
|
|
||||||
statement.Content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -163,11 +154,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
|
||||||
Assert.NotNull(@class);
|
Assert.NotNull(@class);
|
||||||
Assert.Equal(2, @class.Children.Count);
|
Assert.Equal(2, @class.Children.Count);
|
||||||
|
|
||||||
var statement = Assert.IsType<CSharpStatementIRNode>(@class.Children[1]);
|
var node = Assert.IsType<InjectDirectiveIRNode>(@class.Children[1]);
|
||||||
Assert.Equal(
|
Assert.Equal("PropertyType<ModelType>", node.TypeName);
|
||||||
"[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine +
|
Assert.Equal("PropertyName", node.MemberName);
|
||||||
"public PropertyType<ModelType> PropertyName { get; private set; }",
|
|
||||||
statement.Content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private RazorCodeDocument CreateDocument(string content)
|
private RazorCodeDocument CreateDocument(string content)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue