[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 + ">");
|
||||
|
||||
var member = new CSharpStatementIRNode()
|
||||
var injectNode = new InjectDirectiveIRNode()
|
||||
{
|
||||
TypeName = typeName,
|
||||
MemberName = memberName,
|
||||
Source = directive.Source,
|
||||
Content = $"[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]{Environment.NewLine}public {typeName} {memberName} {{ get; private set; }}",
|
||||
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);
|
||||
ModelDirective.Register(b);
|
||||
PageDirective.Register(b);
|
||||
|
||||
b.AddTargetExtension(new InjectDirectiveTargetExtension());
|
||||
|
||||
b.Features.Add(new ModelExpressionPass());
|
||||
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.
|
||||
// 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.Text;
|
||||
using Microsoft.AspNetCore.Razor.Evolution;
|
||||
|
|
@ -36,11 +35,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
|
|||
Assert.NotNull(@class);
|
||||
Assert.Equal(2, @class.Children.Count);
|
||||
|
||||
var statement = Assert.IsType<CSharpStatementIRNode>(@class.Children[1]);
|
||||
Assert.Equal(
|
||||
"[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine +
|
||||
"public PropertyType PropertyName { get; private set; }",
|
||||
statement.Content);
|
||||
var node = Assert.IsType<InjectDirectiveIRNode>(@class.Children[1]);
|
||||
Assert.Equal("PropertyType", node.TypeName);
|
||||
Assert.Equal("PropertyName", node.MemberName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -68,11 +65,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
|
|||
Assert.NotNull(@class);
|
||||
Assert.Equal(2, @class.Children.Count);
|
||||
|
||||
var statement = Assert.IsType<CSharpStatementIRNode>(@class.Children[1]);
|
||||
Assert.Equal(
|
||||
"[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine +
|
||||
"public PropertyType2 PropertyName { get; private set; }",
|
||||
statement.Content);
|
||||
var node = Assert.IsType<InjectDirectiveIRNode>(@class.Children[1]);
|
||||
Assert.Equal("PropertyType2", node.TypeName);
|
||||
Assert.Equal("PropertyName", node.MemberName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -99,11 +94,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
|
|||
Assert.NotNull(@class);
|
||||
Assert.Equal(2, @class.Children.Count);
|
||||
|
||||
var statement = Assert.IsType<CSharpStatementIRNode>(@class.Children[1]);
|
||||
Assert.Equal(
|
||||
"[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine +
|
||||
"public PropertyType<dynamic> PropertyName { get; private set; }",
|
||||
statement.Content);
|
||||
var node = Assert.IsType<InjectDirectiveIRNode>(@class.Children[1]);
|
||||
Assert.Equal("PropertyType<dynamic>", node.TypeName);
|
||||
Assert.Equal("PropertyName", node.MemberName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -131,11 +124,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
|
|||
Assert.NotNull(@class);
|
||||
Assert.Equal(2, @class.Children.Count);
|
||||
|
||||
var statement = Assert.IsType<CSharpStatementIRNode>(@class.Children[1]);
|
||||
Assert.Equal(
|
||||
"[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine +
|
||||
"public PropertyType<ModelType> PropertyName { get; private set; }",
|
||||
statement.Content);
|
||||
var node = Assert.IsType<InjectDirectiveIRNode>(@class.Children[1]);
|
||||
Assert.Equal("PropertyType<ModelType>", node.TypeName);
|
||||
Assert.Equal("PropertyName", node.MemberName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -163,11 +154,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
|
|||
Assert.NotNull(@class);
|
||||
Assert.Equal(2, @class.Children.Count);
|
||||
|
||||
var statement = Assert.IsType<CSharpStatementIRNode>(@class.Children[1]);
|
||||
Assert.Equal(
|
||||
"[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine +
|
||||
"public PropertyType<ModelType> PropertyName { get; private set; }",
|
||||
statement.Content);
|
||||
var node = Assert.IsType<InjectDirectiveIRNode>(@class.Children[1]);
|
||||
Assert.Equal("PropertyType<ModelType>", node.TypeName);
|
||||
Assert.Equal("PropertyName", node.MemberName);
|
||||
}
|
||||
|
||||
private RazorCodeDocument CreateDocument(string content)
|
||||
|
|
|
|||
Loading…
Reference in New Issue