aspnetcore/src/Microsoft.AspNetCore.Mvc.Ra.../AssemblyAttributeInjectionP...

77 lines
2.9 KiB
C#

// 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.Diagnostics;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
{
public class AssemblyAttributeInjectionPass : RazorIRPassBase, IRazorIROptimizationPass
{
private const string RazorViewAttribute = "global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute";
private const string RazorPageAttribute = "global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute";
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIRNode irDocument)
{
var @namespace = irDocument.FindPrimaryNamespace();
if (@namespace == null || string.IsNullOrEmpty(@namespace.Content))
{
// No namespace node or it's incomplete. Skip.
return;
}
var @class = irDocument.FindPrimaryClass();
if (@class == null || string.IsNullOrEmpty(@class.Name))
{
// No class node or it's incomplete. Skip.
return;
}
var generatedTypeName = $"{@namespace.Content}.{@class.Name}";
var path = codeDocument.GetRelativePath();
var escapedPath = EscapeAsVerbatimLiteral(path);
string attribute;
if (irDocument.DocumentKind == MvcViewDocumentClassifierPass.MvcViewDocumentKind)
{
attribute = $"[assembly:{RazorViewAttribute}({escapedPath}, typeof({generatedTypeName}))]";
}
else if (irDocument.DocumentKind == RazorPageDocumentClassifierPass.RazorPageDocumentKind &&
PageDirective.TryGetPageDirective(irDocument, out var pageDirective))
{
var escapedRoutePrefix = EscapeAsVerbatimLiteral(pageDirective.RouteTemplate);
attribute = $"[assembly:{RazorPageAttribute}({escapedPath}, typeof({generatedTypeName}), {escapedRoutePrefix})]";
}
else
{
return;
}
var index = irDocument.Children.IndexOf(@namespace);
Debug.Assert(index >= 0);
var pageAttribute = new CSharpCodeIRNode();
RazorIRBuilder.Create(pageAttribute)
.Add(new RazorIRToken()
{
Kind = RazorIRToken.TokenKind.CSharp,
Content = attribute,
});
irDocument.Children.Insert(index, pageAttribute);
}
private static string EscapeAsVerbatimLiteral(string value)
{
if (value == null)
{
return "null";
}
value = value.Replace("\"", "\"\"");
return $"@\"{value}\"";
}
}
}