Add support for type parameters to class nodes
This change will allow someone extending Razor to use generic type parameters in generated classes. There's no user-level extensibility provided here yet, as in there is no language support for adding type parameters.
This commit is contained in:
parent
ae42d7599d
commit
d1c0ab587c
|
|
@ -60,7 +60,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
|
|||
WriteTargetElementString(context.CodeWriter, node.TagHelper);
|
||||
|
||||
// Initialize declaration.
|
||||
using (context.CodeWriter.BuildClassDeclaration(PublicModifiers, node.ClassName, TagHelperTypeName, interfaces: null))
|
||||
using (context.CodeWriter.BuildClassDeclaration(
|
||||
PublicModifiers,
|
||||
node.ClassName,
|
||||
TagHelperTypeName,
|
||||
interfaces: null,
|
||||
typeParameters: null))
|
||||
{
|
||||
// Add view component helper.
|
||||
context.CodeWriter.WriteVariableDeclaration(
|
||||
|
|
|
|||
|
|
@ -60,7 +60,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
WriteTargetElementString(context.CodeWriter, node.TagHelper);
|
||||
|
||||
// Initialize declaration.
|
||||
using (context.CodeWriter.BuildClassDeclaration(PublicModifiers, node.ClassName, TagHelperTypeName, interfaces: null))
|
||||
using (context.CodeWriter.BuildClassDeclaration(
|
||||
PublicModifiers,
|
||||
node.ClassName,
|
||||
TagHelperTypeName,
|
||||
interfaces: null,
|
||||
typeParameters: null))
|
||||
{
|
||||
// Add view component helper.
|
||||
context.CodeWriter.WriteVariableDeclaration(
|
||||
|
|
|
|||
|
|
@ -374,7 +374,8 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
|
|||
IList<string> modifiers,
|
||||
string name,
|
||||
string baseType,
|
||||
IEnumerable<string> interfaces)
|
||||
IList<string> interfaces,
|
||||
IList<string> typeParameters)
|
||||
{
|
||||
for (var i = 0; i < modifiers.Count; i++)
|
||||
{
|
||||
|
|
@ -385,8 +386,15 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
|
|||
writer.Write("class ");
|
||||
writer.Write(name);
|
||||
|
||||
if (typeParameters != null && typeParameters.Count > 0)
|
||||
{
|
||||
writer.Write("<");
|
||||
writer.Write(string.Join(", ", typeParameters));
|
||||
writer.Write(">");
|
||||
}
|
||||
|
||||
var hasBaseType = !string.IsNullOrEmpty(baseType);
|
||||
var hasInterfaces = interfaces != null && interfaces.Count() > 0;
|
||||
var hasInterfaces = interfaces != null && interfaces.Count > 0;
|
||||
|
||||
if (hasBaseType || hasInterfaces)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -78,8 +78,8 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
|
|||
{
|
||||
algorithmId = "{8829d00f-11b8-4213-878b-770e8597ac16}";
|
||||
}
|
||||
else if (string.Equals(algorithm, HashAlgorithmName.SHA1.Name, StringComparison.Ordinal) ||
|
||||
|
||||
else if (string.Equals(algorithm, HashAlgorithmName.SHA1.Name, StringComparison.Ordinal) ||
|
||||
|
||||
// In 2.0, we didn't actually expose the name of the algorithm, so it's possible we could get null here.
|
||||
// If that's the case, we just assume SHA1 since that's the only thing we supported in 2.0.
|
||||
algorithm == null)
|
||||
|
|
@ -88,7 +88,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
|
|||
}
|
||||
else
|
||||
{
|
||||
var supportedAlgorithms = string.Join(" ", new string[]
|
||||
var supportedAlgorithms = string.Join(" ", new string[]
|
||||
{
|
||||
HashAlgorithmName.SHA1.Name,
|
||||
HashAlgorithmName.SHA256.Name
|
||||
|
|
@ -143,7 +143,12 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
|
|||
|
||||
public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
|
||||
{
|
||||
using (Context.CodeWriter.BuildClassDeclaration(node.Modifiers, node.ClassName, node.BaseType, node.Interfaces))
|
||||
using (Context.CodeWriter.BuildClassDeclaration(
|
||||
node.Modifiers,
|
||||
node.ClassName,
|
||||
node.BaseType,
|
||||
node.Interfaces,
|
||||
node.TypeParameters.Select(p => p.ParameterName).ToArray()))
|
||||
{
|
||||
VisitDefault(node);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
|
|||
|
||||
public string BaseType { get; set; }
|
||||
|
||||
public IList<string> Interfaces { get; set; }
|
||||
public IList<string> Interfaces { get; set; } = new List<string>();
|
||||
|
||||
public IList<TypeParameter> TypeParameters { get; set; } = new List<TypeParameter>();
|
||||
|
||||
public override void Accept(IntermediateNodeVisitor visitor)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
// 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.Intermediate
|
||||
{
|
||||
public sealed class TypeParameter
|
||||
{
|
||||
public string ParameterName { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -218,6 +218,11 @@ namespace TestNamespace
|
|||
},
|
||||
BaseType = "TestBase",
|
||||
Interfaces = new List<string> { "IFoo", "IBar", },
|
||||
TypeParameters = new List<TypeParameter>
|
||||
{
|
||||
new TypeParameter() { ParameterName = "TKey", },
|
||||
new TypeParameter() { ParameterName = "TValue", },
|
||||
},
|
||||
ClassName = "TestClass",
|
||||
});
|
||||
|
||||
|
|
@ -236,7 +241,7 @@ namespace TestNamespace
|
|||
@"#pragma checksum ""test.cshtml"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""da39a3ee5e6b4b0d3255bfef95601890afd80709""
|
||||
// <auto-generated/>
|
||||
#pragma warning disable 1591
|
||||
internal class TestClass : TestBase, IFoo, IBar
|
||||
internal class TestClass<TKey, TValue> : TestBase, IFoo, IBar
|
||||
{
|
||||
}
|
||||
#pragma warning restore 1591
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||
|
|
@ -66,6 +67,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
|
||||
engine.ConfigureClass((document, @class) =>
|
||||
{
|
||||
@class.TypeParameters = new[] { new TypeParameter() { ParameterName = "TValue", }, };
|
||||
@class.Interfaces = new[] { "global::System.IDisposable" };
|
||||
@class.BaseType = "CustomBaseType";
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace Razor
|
|||
{
|
||||
#line hidden
|
||||
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"38aa8e26c5d2a85c61d8e93fe69dd326fe82671b", @"/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.cshtml")]
|
||||
protected internal class MyClass : CustomBaseType, global::System.IDisposable
|
||||
protected internal class MyClass<TValue> : CustomBaseType, global::System.IDisposable
|
||||
{
|
||||
#pragma warning disable 1998
|
||||
public async override global::System.Threading.Tasks.Task ExecuteAsync()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// 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 System.IO;
|
||||
using System.Linq;
|
||||
|
|
@ -12,7 +13,7 @@ using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
|||
namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||
{
|
||||
// Serializes single IR nodes (shallow).
|
||||
public class IntermediateNodeWriter :
|
||||
public class IntermediateNodeWriter :
|
||||
IntermediateNodeVisitor,
|
||||
IExtensionIntermediateNodeVisitor<SectionIntermediateNode>
|
||||
{
|
||||
|
|
@ -32,7 +33,21 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
|
||||
public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
|
||||
{
|
||||
WriteContentNode(node, string.Join(" ", node.Modifiers), node.ClassName, node.BaseType, string.Join(", ", node.Interfaces ?? new List<string>()));
|
||||
var entries = new List<string>()
|
||||
{
|
||||
string.Join(" ", node.Modifiers),
|
||||
node.ClassName,
|
||||
node.BaseType,
|
||||
string.Join(", ", node.Interfaces ?? Array.Empty<string>())
|
||||
};
|
||||
|
||||
// Avoid adding the type parameters to the baseline if they aren't present.
|
||||
if (node.TypeParameters != null && node.TypeParameters.Count > 0)
|
||||
{
|
||||
entries.Add(string.Join(", ", node.TypeParameters));
|
||||
}
|
||||
|
||||
WriteContentNode(node, entries.ToArray());
|
||||
}
|
||||
|
||||
public override void VisitCSharpExpressionAttributeValue(CSharpExpressionAttributeValueIntermediateNode node)
|
||||
|
|
|
|||
Loading…
Reference in New Issue