Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
using System.Globalization;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using Microsoft.AspNetCore.Razor.PooledObjects;
using Microsoft.Extensions.ObjectPool;

namespace Microsoft.AspNetCore.Razor.Language.Syntax;

Expand All @@ -22,6 +24,12 @@ internal abstract class GreenNode
private static readonly ConditionalWeakTable<GreenNode, SyntaxAnnotation[]> AnnotationsTable =
new ConditionalWeakTable<GreenNode, SyntaxAnnotation[]>();

/// <summary>
/// Pool of StringWriters for use in <see cref="ToString()"/>. Users should not dispose the StringWriter directly
/// (but should dispose of the PooledObject returned from Pool.GetPooledObject).
/// </summary>
private static readonly ObjectPool<StringWriter> StringWriterPool = DefaultPool.Create(Policy.Instance);

private int _width;
private byte _slotCount;

Expand Down Expand Up @@ -234,10 +242,11 @@ private string GetDebuggerDisplay()

public override string ToString()
{
using var _ = StringBuilderPool.GetPooledObject(out var builder);
using var writer = new StringWriter(builder, CultureInfo.InvariantCulture);
using var _ = StringWriterPool.GetPooledObject(out var writer);

WriteTo(writer);
return builder.ToString();

return writer.ToString();
}

public void WriteTo(TextWriter writer)
Expand Down Expand Up @@ -351,4 +360,30 @@ public SyntaxNode CreateRed()
public abstract TResult Accept<TResult>(InternalSyntax.SyntaxVisitor<TResult> visitor);

public abstract void Accept(InternalSyntax.SyntaxVisitor visitor);

private sealed class Policy : IPooledObjectPolicy<StringWriter>
{
public static readonly Policy Instance = new();

private Policy()
{
}

public StringWriter Create()
=> new StringWriter(new StringBuilder(), CultureInfo.InvariantCulture);

public bool Return(StringWriter writer)
{
var builder = writer.GetStringBuilder();

// Very similar to StringBuilderPool.Policy implementation.
builder.Clear();
if (builder.Capacity > DefaultPool.MaximumObjectSize)
{
builder.Capacity = DefaultPool.MaximumObjectSize;
}

return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.AspNetCore.Razor.PooledObjects;
using Microsoft.CodeAnalysis.CSharp;

namespace Microsoft.AspNetCore.Razor.Language.Syntax;
Expand Down Expand Up @@ -303,11 +302,7 @@ public static TRoot InsertNodesAfter<TRoot>(this TRoot root, SyntaxNode nodeInLi

public static string GetContent<TNode>(this TNode node) where TNode : SyntaxNode
{
using var _ = StringBuilderPool.GetPooledObject(out var builder);
using var writer = new System.IO.StringWriter(builder);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StringWriter(builder)

Here's where GetContent implicity specified CultureInfo.CurrentCulture

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't think you need to worry about CultureInfo for the StringWriter. GreenNode.WriteTo delegates to GreenNode.WriteTokenTo to do any actually writing. WriteTokenTo is only overridden by SyntaxToken and it just writes a string. IOW, nothing actually writes anything other than strings, so it's essentially culture-neutral.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I was hoping. Went ahead and changed to always use InvariantCulture. Thanks!

node.Green.WriteTo(writer);

return writer.ToString();
return node.Green.ToString();
}

private sealed class DiagnosticSyntaxWalker(List<RazorDiagnostic> diagnostics) : SyntaxWalker
Expand Down