aspnetcore/src/Microsoft.AspNetCore.Razor..../Extensions/DesignTimeDirectiveTargetEx...

138 lines
5.2 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;
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
internal class DesignTimeDirectiveTargetExtension : IDesignTimeDirectiveTargetExtension
{
private const string DirectiveTokenHelperMethodName = "__RazorDirectiveTokenHelpers__";
private const string TypeHelper = "__typeHelper";
public void WriteDesignTimeDirective(CSharpRenderingContext context, DesignTimeDirectiveIntermediateNode node)
{
context.Writer
.WriteLine("#pragma warning disable 219")
.WriteLine($"private void {DirectiveTokenHelperMethodName}() {{");
for (var i = 0; i < node.Children.Count; i++)
{
if (node.Children[i] is DirectiveTokenIntermediateNode n)
{
WriteDesignTimeDirectiveToken(context, n);
}
}
context.Writer
.WriteLine("}")
.WriteLine("#pragma warning restore 219");
}
private void WriteDesignTimeDirectiveToken(CSharpRenderingContext context, DirectiveTokenIntermediateNode node)
{
var tokenKind = node.Descriptor.Kind;
if (!node.Source.HasValue ||
!string.Equals(
context.SourceDocument?.FilePath,
node.Source.Value.FilePath,
StringComparison.OrdinalIgnoreCase))
{
// We don't want to handle directives from imports.
return;
}
// Wrap the directive token in a lambda to isolate variable names.
context.Writer
.Write("((")
.Write(typeof(Action).FullName)
.Write(")(");
using (context.Writer.BuildLambda())
{
var originalIndent = context.Writer.CurrentIndent;
context.Writer.CurrentIndent = 0;
switch (tokenKind)
{
case DirectiveTokenKind.Type:
// {node.Content} __typeHelper = default({node.Content});
context.AddLineMappingFor(node);
context.Writer
.Write(node.Content)
.Write(" ")
.WriteStartAssignment(TypeHelper)
.Write("default(")
.Write(node.Content)
.WriteLine(");");
break;
case DirectiveTokenKind.Member:
// global::System.Object {node.content} = null;
context.Writer
.Write("global::")
.Write(typeof(object).FullName)
.Write(" ");
context.AddLineMappingFor(node);
context.Writer
.Write(node.Content)
.WriteLine(" = null;");
break;
case DirectiveTokenKind.Namespace:
// global::System.Object __typeHelper = nameof({node.Content});
context.Writer
.Write("global::")
.Write(typeof(object).FullName)
.Write(" ")
.WriteStartAssignment(TypeHelper);
context.Writer.Write("nameof(");
context.AddLineMappingFor(node);
context.Writer
.Write(node.Content)
.WriteLine(");");
break;
case DirectiveTokenKind.String:
// global::System.Object __typeHelper = "{node.Content}";
context.Writer
.Write("global::")
.Write(typeof(object).FullName)
.Write(" ")
.WriteStartAssignment(TypeHelper);
if (node.Content.StartsWith("\"", StringComparison.Ordinal))
{
context.AddLineMappingFor(node);
context.Writer.Write(node.Content);
}
else
{
context.Writer.Write("\"");
context.AddLineMappingFor(node);
context.Writer
.Write(node.Content)
.Write("\"");
}
context.Writer.WriteLine(";");
break;
}
context.Writer.CurrentIndent = originalIndent;
}
context.Writer.WriteLine("))();");
}
}
}