зеркало из https://github.com/dotnet/razor.git
Clean up and enable nullability for CodeRenderingContext and DefaultDocumentWriter
This commit is contained in:
Родитель
7a9f32ea37
Коммит
6593264ac6
|
@ -4,7 +4,6 @@
|
|||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Razor.PooledObjects;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language;
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
|
@ -28,6 +26,9 @@ public sealed class CodeRenderingContext : IDisposable
|
|||
private readonly ImmutableArray<SourceMapping>.Builder _sourceMappings;
|
||||
private readonly ImmutableArray<LinePragma>.Builder _linePragmas;
|
||||
|
||||
private IntermediateNodeVisitor? _visitor;
|
||||
public IntermediateNodeVisitor Visitor => _visitor.AssumeNotNull();
|
||||
|
||||
public string DocumentKind => _documentNode.DocumentKind;
|
||||
|
||||
public CodeRenderingContext(
|
||||
|
@ -74,12 +75,16 @@ public sealed class CodeRenderingContext : IDisposable
|
|||
CodeWriter.Dispose();
|
||||
}
|
||||
|
||||
// This will be initialized by the document writer when the context is 'live'.
|
||||
public IntermediateNodeVisitor Visitor { get; set; }
|
||||
// This will be called by the document writer when the context is 'live'.
|
||||
public void SetVisitor(IntermediateNodeVisitor visitor)
|
||||
{
|
||||
_visitor = visitor;
|
||||
}
|
||||
|
||||
public IntermediateNodeWriter NodeWriter => _scopeStack.Peek().Writer;
|
||||
|
||||
public IntermediateNode Parent => _ancestorStack.Count == 0 ? null : _ancestorStack.Peek();
|
||||
public IntermediateNode? Parent
|
||||
=> _ancestorStack.Count == 0 ? null : _ancestorStack.Peek();
|
||||
|
||||
public void AddDiagnostic(RazorDiagnostic diagnostic)
|
||||
{
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
|
@ -10,16 +8,10 @@ using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
|||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration;
|
||||
|
||||
internal class DefaultDocumentWriter : DocumentWriter
|
||||
internal class DefaultDocumentWriter(CodeTarget codeTarget, RazorCodeGenerationOptions options) : DocumentWriter
|
||||
{
|
||||
private readonly CodeTarget _codeTarget;
|
||||
private readonly RazorCodeGenerationOptions _options;
|
||||
|
||||
public DefaultDocumentWriter(CodeTarget codeTarget, RazorCodeGenerationOptions options)
|
||||
{
|
||||
_codeTarget = codeTarget;
|
||||
_options = options;
|
||||
}
|
||||
private readonly CodeTarget _codeTarget = codeTarget;
|
||||
private readonly RazorCodeGenerationOptions _options = options;
|
||||
|
||||
public override RazorCSharpDocument WriteDocument(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
|
||||
{
|
||||
|
@ -32,37 +24,35 @@ internal class DefaultDocumentWriter : DocumentWriter
|
|||
documentNode,
|
||||
_options);
|
||||
|
||||
context.Visitor = new Visitor(_codeTarget, context);
|
||||
context.SetVisitor(new Visitor(_codeTarget, context));
|
||||
|
||||
context.Visitor.VisitDocument(documentNode);
|
||||
|
||||
var csharp = context.CodeWriter.GenerateCode();
|
||||
var generatedCode = context.CodeWriter.GenerateCode();
|
||||
|
||||
return new RazorCSharpDocument(
|
||||
codeDocument,
|
||||
csharp,
|
||||
generatedCode,
|
||||
_options,
|
||||
context.GetDiagnostics(),
|
||||
context.GetSourceMappings(),
|
||||
context.GetLinePragmas());
|
||||
}
|
||||
|
||||
private class Visitor : IntermediateNodeVisitor
|
||||
private sealed class Visitor(CodeTarget codeTarget, CodeRenderingContext context) : IntermediateNodeVisitor
|
||||
{
|
||||
private readonly CodeRenderingContext _context;
|
||||
private readonly CodeTarget _target;
|
||||
private readonly CodeRenderingContext _context = context;
|
||||
private readonly CodeTarget _codeTarget = codeTarget;
|
||||
|
||||
public Visitor(CodeTarget target, CodeRenderingContext context)
|
||||
{
|
||||
_target = target;
|
||||
_context = context;
|
||||
}
|
||||
|
||||
private CodeRenderingContext Context => _context;
|
||||
private CodeWriter CodeWriter => _context.CodeWriter;
|
||||
private IntermediateNodeWriter NodeWriter => _context.NodeWriter;
|
||||
private RazorCodeGenerationOptions Options => _context.Options;
|
||||
|
||||
public override void VisitDocument(DocumentIntermediateNode node)
|
||||
{
|
||||
if (!Context.Options.SuppressChecksum)
|
||||
var codeWriter = CodeWriter;
|
||||
|
||||
if (!Options.SuppressChecksum)
|
||||
{
|
||||
// See http://msdn.microsoft.com/en-us/library/system.codedom.codechecksumpragma.checksumalgorithmid.aspx
|
||||
// And https://github.com/dotnet/roslyn/blob/614299ff83da9959fa07131c6d0ffbc58873b6ae/src/Compilers/Core/Portable/PEWriter/DebugSourceDocument.cs#L67
|
||||
|
@ -70,7 +60,7 @@ internal class DefaultDocumentWriter : DocumentWriter
|
|||
// We only support algorithms that the debugger understands, which is currently SHA1 and SHA256.
|
||||
|
||||
string algorithmId;
|
||||
var algorithm = Context.SourceDocument.Text.ChecksumAlgorithm;
|
||||
var algorithm = _context.SourceDocument.Text.ChecksumAlgorithm;
|
||||
if (algorithm == CodeAnalysis.Text.SourceHashAlgorithm.Sha256)
|
||||
{
|
||||
algorithmId = "{8829d00f-11b8-4213-878b-770e8597ac16}";
|
||||
|
@ -81,80 +71,75 @@ internal class DefaultDocumentWriter : DocumentWriter
|
|||
}
|
||||
else
|
||||
{
|
||||
var supportedAlgorithms = string.Join(" ", new string[]
|
||||
{
|
||||
HashAlgorithmName.SHA1.Name,
|
||||
HashAlgorithmName.SHA256.Name
|
||||
});
|
||||
string?[] supportedAlgorithms = [HashAlgorithmName.SHA1.Name, HashAlgorithmName.SHA256.Name];
|
||||
|
||||
var message = Resources.FormatUnsupportedChecksumAlgorithm(
|
||||
algorithm,
|
||||
supportedAlgorithms,
|
||||
nameof(RazorCodeGenerationOptions) + "." + nameof(RazorCodeGenerationOptions.SuppressChecksum),
|
||||
string.Join(" ", supportedAlgorithms),
|
||||
$"{nameof(RazorCodeGenerationOptions)}.{nameof(RazorCodeGenerationOptions.SuppressChecksum)}",
|
||||
bool.TrueString);
|
||||
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
||||
var sourceDocument = Context.SourceDocument;
|
||||
var sourceDocument = _context.SourceDocument;
|
||||
|
||||
var checksum = ChecksumUtilities.BytesToString(sourceDocument.Text.GetChecksum());
|
||||
if (!string.IsNullOrEmpty(checksum))
|
||||
var filePath = sourceDocument.FilePath.AssumeNotNull();
|
||||
|
||||
if (checksum.Length > 0)
|
||||
{
|
||||
Context.CodeWriter
|
||||
.Write("#pragma checksum \"")
|
||||
.Write(sourceDocument.FilePath)
|
||||
.Write("\" \"")
|
||||
.Write(algorithmId)
|
||||
.Write("\" \"")
|
||||
.Write(checksum)
|
||||
.WriteLine("\"");
|
||||
codeWriter.WriteLine($"#pragma checksum \"{filePath}\" \"{algorithmId}\" \"{checksum}\"");
|
||||
}
|
||||
}
|
||||
|
||||
Context.CodeWriter
|
||||
codeWriter
|
||||
.WriteLine("// <auto-generated/>")
|
||||
.WriteLine("#pragma warning disable 1591");
|
||||
|
||||
VisitDefault(node);
|
||||
|
||||
Context.CodeWriter.WriteLine("#pragma warning restore 1591");
|
||||
codeWriter.WriteLine("#pragma warning restore 1591");
|
||||
}
|
||||
|
||||
public override void VisitUsingDirective(UsingDirectiveIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteUsingDirective(Context, node);
|
||||
NodeWriter.WriteUsingDirective(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node)
|
||||
{
|
||||
using (Context.CodeWriter.BuildNamespace(node.Content, node.Source, Context))
|
||||
var codeWriter = CodeWriter;
|
||||
|
||||
using (codeWriter.BuildNamespace(node.Content, node.Source, _context))
|
||||
{
|
||||
if (node.Children.OfType<UsingDirectiveIntermediateNode>().Any())
|
||||
{
|
||||
// Tooling needs at least one line directive before using directives, otherwise Roslyn will
|
||||
// not offer to create a new one. The last using in the group will output a hidden line
|
||||
// directive after itself.
|
||||
Context.CodeWriter.WriteLine("#line default");
|
||||
codeWriter.WriteLine("#line default");
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there are no using directives, we output the hidden directive here.
|
||||
Context.CodeWriter.WriteLine("#line hidden");
|
||||
codeWriter.WriteLine("#line hidden");
|
||||
}
|
||||
|
||||
VisitDefault(node);
|
||||
}
|
||||
}
|
||||
|
||||
public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
|
||||
{
|
||||
using (Context.CodeWriter.BuildClassDeclaration(
|
||||
using (CodeWriter.BuildClassDeclaration(
|
||||
node.Modifiers,
|
||||
node.ClassName,
|
||||
node.BaseType,
|
||||
node.Interfaces,
|
||||
node.TypeParameters,
|
||||
Context,
|
||||
useNullableContext: !Context.Options.SuppressNullabilityEnforcement && node.Annotations[CommonAnnotations.NullableContext] is not null))
|
||||
_context,
|
||||
useNullableContext: !Options.SuppressNullabilityEnforcement && node.Annotations[CommonAnnotations.NullableContext] is not null))
|
||||
{
|
||||
VisitDefault(node);
|
||||
}
|
||||
|
@ -162,100 +147,99 @@ internal class DefaultDocumentWriter : DocumentWriter
|
|||
|
||||
public override void VisitMethodDeclaration(MethodDeclarationIntermediateNode node)
|
||||
{
|
||||
Context.CodeWriter.WriteLine("#pragma warning disable 1998");
|
||||
var codeWriter = CodeWriter;
|
||||
|
||||
codeWriter.WriteLine("#pragma warning disable 1998");
|
||||
|
||||
for (var i = 0; i < node.Modifiers.Count; i++)
|
||||
{
|
||||
Context.CodeWriter.Write(node.Modifiers[i]);
|
||||
Context.CodeWriter.Write(" ");
|
||||
codeWriter.Write($"{node.Modifiers[i]} ");
|
||||
}
|
||||
|
||||
Context.CodeWriter.Write(node.ReturnType);
|
||||
Context.CodeWriter.Write(" ");
|
||||
codeWriter.Write($"{node.ReturnType} ");
|
||||
codeWriter.Write($"{node.MethodName}(");
|
||||
|
||||
Context.CodeWriter.Write(node.MethodName);
|
||||
Context.CodeWriter.Write("(");
|
||||
var isFirst = true;
|
||||
|
||||
for (var i = 0; i < node.Parameters.Count; i++)
|
||||
{
|
||||
var parameter = node.Parameters[i];
|
||||
|
||||
if (isFirst)
|
||||
{
|
||||
isFirst = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
codeWriter.Write(", ");
|
||||
}
|
||||
|
||||
for (var j = 0; j < parameter.Modifiers.Count; j++)
|
||||
{
|
||||
Context.CodeWriter.Write(parameter.Modifiers[j]);
|
||||
Context.CodeWriter.Write(" ");
|
||||
codeWriter.Write($"{parameter.Modifiers[j]} ");
|
||||
}
|
||||
|
||||
Context.CodeWriter.Write(parameter.TypeName);
|
||||
Context.CodeWriter.Write(" ");
|
||||
|
||||
Context.CodeWriter.Write(parameter.ParameterName);
|
||||
|
||||
if (i < node.Parameters.Count - 1)
|
||||
{
|
||||
Context.CodeWriter.Write(", ");
|
||||
}
|
||||
codeWriter.Write($"{parameter.TypeName} {parameter.ParameterName}");
|
||||
}
|
||||
|
||||
Context.CodeWriter.Write(")");
|
||||
Context.CodeWriter.WriteLine();
|
||||
codeWriter.WriteLine(")");
|
||||
|
||||
using (Context.CodeWriter.BuildScope())
|
||||
using (codeWriter.BuildScope())
|
||||
{
|
||||
VisitDefault(node);
|
||||
}
|
||||
|
||||
Context.CodeWriter.WriteLine("#pragma warning restore 1998");
|
||||
codeWriter.WriteLine("#pragma warning restore 1998");
|
||||
}
|
||||
|
||||
public override void VisitFieldDeclaration(FieldDeclarationIntermediateNode node)
|
||||
{
|
||||
Context.CodeWriter.WriteField(node.SuppressWarnings, node.Modifiers, node.FieldType, node.FieldName);
|
||||
CodeWriter.WriteField(node.SuppressWarnings, node.Modifiers, node.FieldType, node.FieldName);
|
||||
}
|
||||
|
||||
public override void VisitPropertyDeclaration(PropertyDeclarationIntermediateNode node)
|
||||
{
|
||||
Context.CodeWriter.WriteAutoPropertyDeclaration(node.Modifiers, node.PropertyType, node.PropertyName);
|
||||
CodeWriter.WriteAutoPropertyDeclaration(node.Modifiers, node.PropertyType, node.PropertyName);
|
||||
}
|
||||
|
||||
public override void VisitExtension(ExtensionIntermediateNode node)
|
||||
{
|
||||
node.WriteNode(_target, Context);
|
||||
node.WriteNode(_codeTarget, _context);
|
||||
}
|
||||
|
||||
public override void VisitCSharpExpression(CSharpExpressionIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteCSharpExpression(Context, node);
|
||||
NodeWriter.WriteCSharpExpression(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitCSharpCode(CSharpCodeIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteCSharpCode(Context, node);
|
||||
NodeWriter.WriteCSharpCode(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitHtmlAttribute(HtmlAttributeIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteHtmlAttribute(Context, node);
|
||||
NodeWriter.WriteHtmlAttribute(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitHtmlAttributeValue(HtmlAttributeValueIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteHtmlAttributeValue(Context, node);
|
||||
NodeWriter.WriteHtmlAttributeValue(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitCSharpExpressionAttributeValue(CSharpExpressionAttributeValueIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteCSharpExpressionAttributeValue(Context, node);
|
||||
NodeWriter.WriteCSharpExpressionAttributeValue(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitCSharpCodeAttributeValue(CSharpCodeAttributeValueIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteCSharpCodeAttributeValue(Context, node);
|
||||
NodeWriter.WriteCSharpCodeAttributeValue(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitHtml(HtmlContentIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteHtmlContent(Context, node);
|
||||
NodeWriter.WriteHtmlContent(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitTagHelper(TagHelperIntermediateNode node)
|
||||
|
@ -265,67 +249,67 @@ internal class DefaultDocumentWriter : DocumentWriter
|
|||
|
||||
public override void VisitComponent(ComponentIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteComponent(Context, node);
|
||||
NodeWriter.WriteComponent(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitComponentAttribute(ComponentAttributeIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteComponentAttribute(Context, node);
|
||||
NodeWriter.WriteComponentAttribute(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitComponentChildContent(ComponentChildContentIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteComponentChildContent(Context, node);
|
||||
NodeWriter.WriteComponentChildContent(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitComponentTypeArgument(ComponentTypeArgumentIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteComponentTypeArgument(Context, node);
|
||||
NodeWriter.WriteComponentTypeArgument(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitComponentTypeInferenceMethod(ComponentTypeInferenceMethodIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteComponentTypeInferenceMethod(Context, node);
|
||||
NodeWriter.WriteComponentTypeInferenceMethod(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitMarkupElement(MarkupElementIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteMarkupElement(Context, node);
|
||||
NodeWriter.WriteMarkupElement(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitMarkupBlock(MarkupBlockIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteMarkupBlock(Context, node);
|
||||
NodeWriter.WriteMarkupBlock(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitReferenceCapture(ReferenceCaptureIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteReferenceCapture(Context, node);
|
||||
NodeWriter.WriteReferenceCapture(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitSetKey(SetKeyIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteSetKey(Context, node);
|
||||
NodeWriter.WriteSetKey(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitSplat(SplatIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteSplat(Context, node);
|
||||
NodeWriter.WriteSplat(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitRenderMode(RenderModeIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteRenderMode(Context, node);
|
||||
NodeWriter.WriteRenderMode(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitFormName(FormNameIntermediateNode node)
|
||||
{
|
||||
Context.NodeWriter.WriteFormName(Context, node);
|
||||
NodeWriter.WriteFormName(_context, node);
|
||||
}
|
||||
|
||||
public override void VisitDefault(IntermediateNode node)
|
||||
{
|
||||
Context.RenderChildren(node);
|
||||
_context.RenderChildren(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ public static class TestCodeRenderingContext
|
|||
var options = ConfigureOptions(RazorCodeGenerationOptions.DesignTimeDefault, newLineString, suppressUniqueIds);
|
||||
|
||||
var context = new CodeRenderingContext(nodeWriter, source, documentNode, options);
|
||||
context.Visitor = new RenderChildrenVisitor(context);
|
||||
context.SetVisitor(new RenderChildrenVisitor(context.CodeWriter));
|
||||
|
||||
return context;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ public static class TestCodeRenderingContext
|
|||
var options = ConfigureOptions(RazorCodeGenerationOptions.Default, newLineString, suppressUniqueIds);
|
||||
|
||||
var context = new CodeRenderingContext(nodeWriter, source, documentNode, options);
|
||||
context.Visitor = new RenderChildrenVisitor(context);
|
||||
context.SetVisitor(new RenderChildrenVisitor(context.CodeWriter));
|
||||
|
||||
return context;
|
||||
}
|
||||
|
@ -67,17 +67,11 @@ public static class TestCodeRenderingContext
|
|||
return builder.Build();
|
||||
}
|
||||
|
||||
private class RenderChildrenVisitor : IntermediateNodeVisitor
|
||||
private class RenderChildrenVisitor(CodeWriter writer) : IntermediateNodeVisitor
|
||||
{
|
||||
private readonly CodeRenderingContext _context;
|
||||
public RenderChildrenVisitor(CodeRenderingContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public override void VisitDefault(IntermediateNode node)
|
||||
{
|
||||
_context.CodeWriter.WriteLine("Render Children");
|
||||
writer.WriteLine("Render Children");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче