aspnetcore/src/Microsoft.AspNetCore.Razor..../CodeGeneration/DefaultDocumentWriter.cs

218 lines
7.8 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 System.Linq;
using System.Text;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
internal class DefaultDocumentWriter : DocumentWriter
{
private readonly CodeTarget _codeTarget;
private readonly RazorCodeGenerationOptions _options;
public DefaultDocumentWriter(CodeTarget codeTarget, RazorCodeGenerationOptions options)
{
_codeTarget = codeTarget;
_options = options;
}
public override RazorCSharpDocument WriteDocument(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
if (codeDocument == null)
{
throw new ArgumentNullException(nameof(codeDocument));
}
if (documentNode == null)
{
throw new ArgumentNullException(nameof(documentNode));
}
var context = new DefaultCodeRenderingContext(
new CodeWriter(),
_codeTarget.CreateNodeWriter(),
codeDocument,
documentNode,
_options);
context.Visitor = new Visitor(_codeTarget, context);
context.Visitor.VisitDocument(documentNode);
var cSharp = context.CodeWriter.GenerateCode();
return new DefaultRazorCSharpDocument(
cSharp,
_options,
context.Diagnostics.ToArray(),
context.LineMappings.ToArray());
}
private class Visitor : IntermediateNodeVisitor
{
private readonly DefaultCodeRenderingContext _context;
private readonly CodeTarget _target;
public Visitor(CodeTarget target, DefaultCodeRenderingContext context)
{
_target = target;
_context = context;
}
private DefaultCodeRenderingContext Context => _context;
public override void VisitDocument(DocumentIntermediateNode node)
{
if (!Context.Options.SuppressChecksum)
{
// See http://msdn.microsoft.com/en-us/library/system.codedom.codechecksumpragma.checksumalgorithmid.aspx
const string Sha1AlgorithmId = "{ff1816ec-aa5e-4d10-87f7-6f4963833460}";
var sourceDocument = Context.SourceDocument;
var checksum = sourceDocument.GetChecksum();
var fileHashBuilder = new StringBuilder(checksum.Length * 2);
foreach (var value in checksum)
{
fileHashBuilder.Append(value.ToString("x2"));
}
var bytes = fileHashBuilder.ToString();
if (!string.IsNullOrEmpty(bytes))
{
Context.CodeWriter
.Write("#pragma checksum \"")
.Write(sourceDocument.FilePath)
.Write("\" \"")
.Write(Sha1AlgorithmId)
.Write("\" \"")
.Write(bytes)
.WriteLine("\"");
}
}
Context.CodeWriter
.WriteLine("// <auto-generated/>")
.WriteLine("#pragma warning disable 1591");
VisitDefault(node);
Context.CodeWriter.WriteLine("#pragma warning restore 1591");
}
public override void VisitUsingDirective(UsingDirectiveIntermediateNode node)
{
Context.NodeWriter.WriteUsingDirective(Context, node);
}
public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node)
{
using (Context.CodeWriter.BuildNamespace(node.Content))
{
Context.CodeWriter.WriteLine("#line hidden");
VisitDefault(node);
}
}
public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
{
using (Context.CodeWriter.BuildClassDeclaration(node.Modifiers, node.Name, node.BaseType, node.Interfaces))
{
VisitDefault(node);
}
}
public override void VisitMethodDeclaration(MethodDeclarationIntermediateNode node)
{
Context.CodeWriter.WriteLine("#pragma warning disable 1998");
for (var i = 0; i < node.Modifiers.Count; i++)
{
Context.CodeWriter.Write(node.Modifiers[i]);
Context.CodeWriter.Write(" ");
}
Context.CodeWriter
.Write(node.ReturnType)
.Write(" ")
.Write(node.Name)
.WriteLine("()");
using (Context.CodeWriter.BuildScope())
{
VisitDefault(node);
}
Context.CodeWriter.WriteLine("#pragma warning restore 1998");
}
public override void VisitFieldDeclaration(FieldDeclarationIntermediateNode node)
{
Context.CodeWriter.WriteField(node.Modifiers, node.Type, node.Name);
}
public override void VisitPropertyDeclaration(PropertyDeclarationIntermediateNode node)
{
Context.CodeWriter.WriteAutoPropertyDeclaration(node.Modifiers, node.Type, node.Name);
}
public override void VisitExtension(ExtensionIntermediateNode node)
{
node.WriteNode(_target, Context);
}
public override void VisitCSharpExpression(CSharpExpressionIntermediateNode node)
{
Context.NodeWriter.WriteCSharpExpression(Context, node);
}
public override void VisitCSharpCode(CSharpCodeIntermediateNode node)
{
Context.NodeWriter.WriteCSharpCode(Context, node);
}
public override void VisitHtmlAttribute(HtmlAttributeIntermediateNode node)
{
Context.NodeWriter.WriteHtmlAttribute(Context, node);
}
public override void VisitHtmlAttributeValue(HtmlAttributeValueIntermediateNode node)
{
Context.NodeWriter.WriteHtmlAttributeValue(Context, node);
}
public override void VisitCSharpExpressionAttributeValue(CSharpExpressionAttributeValueIntermediateNode node)
{
Context.NodeWriter.WriteCSharpExpressionAttributeValue(Context, node);
}
public override void VisitCSharpCodeAttributeValue(CSharpCodeAttributeValueIntermediateNode node)
{
Context.NodeWriter.WriteCSharpCodeAttributeValue(Context, node);
}
public override void VisitHtml(HtmlContentIntermediateNode node)
{
Context.NodeWriter.WriteHtmlContent(Context, node);
}
public override void VisitTagHelper(TagHelperIntermediateNode node)
{
var tagHelperRenderingContext = new TagHelperRenderingContext();
using (Context.Push(tagHelperRenderingContext))
{
VisitDefault(node);
}
}
public override void VisitDefault(IntermediateNode node)
{
Context.RenderChildren(node);
}
}
}
}