138 lines
5.2 KiB
C#
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("))();");
|
|
}
|
|
}
|
|
}
|