Skip to content

Commit

Permalink
Merge pull request #68522 from CyrusNajmabadi/stringFolding
Browse files Browse the repository at this point in the history
Reduce allocations in outlining in pathlogical files
  • Loading branch information
CyrusNajmabadi authored Jun 9, 2023
2 parents 403f2ce + ad342f0 commit 7a43937
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Shared.Collections;
using Microsoft.CodeAnalysis.Structure;
using Microsoft.CodeAnalysis.Text;

namespace Microsoft.CodeAnalysis.CSharp.Structure
{
Expand All @@ -19,7 +20,8 @@ protected override void CollectBlockSpans(
CancellationToken cancellationToken)
{
if (node.IsKind(SyntaxKind.StringLiteralExpression) &&
!node.ContainsDiagnostics)
!node.ContainsDiagnostics &&
CouldBeMultiLine())
{
spans.Add(new BlockSpan(
isCollapsible: true,
Expand All @@ -29,6 +31,24 @@ protected override void CollectBlockSpans(
autoCollapse: true,
isDefaultCollapsed: false));
}

return;

bool CouldBeMultiLine()
{
if (node.Token.Kind() is SyntaxKind.MultiLineRawStringLiteralToken or SyntaxKind.Utf8MultiLineRawStringLiteralToken)
return true;

if (node.Token.IsVerbatimStringLiteral())
{
var span = node.Span;
var sourceText = node.SyntaxTree.GetText(cancellationToken);
return sourceText.Lines.GetLineFromPosition(span.Start).LineNumber !=
sourceText.Lines.GetLineFromPosition(span.End).LineNumber;
}

return false;
}
}
}
}
20 changes: 11 additions & 9 deletions src/Features/Core/Portable/Structure/BlockStructureContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,22 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Immutable;
using System.Threading;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.Structure
{
internal sealed class BlockStructureContext
[NonCopyable]
internal readonly struct BlockStructureContext : IDisposable
{
private readonly ImmutableArray<BlockSpan>.Builder _spans = ImmutableArray.CreateBuilder<BlockSpan>();
public readonly ArrayBuilder<BlockSpan> Spans = ArrayBuilder<BlockSpan>.GetInstance();

public SyntaxTree SyntaxTree { get; }
public BlockStructureOptions Options { get; }
public CancellationToken CancellationToken { get; }

internal ImmutableArray<BlockSpan> Spans => _spans.ToImmutable();
public readonly SyntaxTree SyntaxTree;
public readonly BlockStructureOptions Options;
public readonly CancellationToken CancellationToken;

public BlockStructureContext(SyntaxTree syntaxTree, BlockStructureOptions options, CancellationToken cancellationToken)
{
Expand All @@ -24,7 +26,7 @@ public BlockStructureContext(SyntaxTree syntaxTree, BlockStructureOptions option
CancellationToken = cancellationToken;
}

public void AddBlockSpan(BlockSpan span)
=> _spans.Add(span);
public void Dispose()
=> Spans.Free();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ namespace Microsoft.CodeAnalysis.Structure
{
internal abstract class BlockStructureProvider
{
public abstract void ProvideBlockStructure(BlockStructureContext context);
public abstract void ProvideBlockStructure(in BlockStructureContext context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ public override async Task<BlockStructure> GetBlockStructureAsync(
CancellationToken cancellationToken)
{
var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
var context = CreateContext(syntaxTree, options, cancellationToken);

using var context = CreateContext(syntaxTree, options, cancellationToken);
return GetBlockStructure(context, _providers);
}

Expand All @@ -64,7 +63,7 @@ private static BlockStructureContext CreateContext(
}

private static BlockStructure GetBlockStructure(
BlockStructureContext context,
in BlockStructureContext context,
ImmutableArray<BlockStructureProvider> providers)
{
foreach (var provider in providers)
Expand All @@ -73,16 +72,13 @@ private static BlockStructure GetBlockStructure(
return CreateBlockStructure(context);
}

private static BlockStructure CreateBlockStructure(BlockStructureContext context)
private static BlockStructure CreateBlockStructure(in BlockStructureContext context)
{
using var _ = ArrayBuilder<BlockSpan>.GetInstance(out var updatedSpans);
using var _ = ArrayBuilder<BlockSpan>.GetInstance(context.Spans.Count, out var updatedSpans);
foreach (var span in context.Spans)
{
var updatedSpan = UpdateBlockSpan(span, context.Options);
updatedSpans.Add(updatedSpan);
}
updatedSpans.Add(UpdateBlockSpan(span, context.Options));

return new BlockStructure(updatedSpans.ToImmutable());
return new BlockStructure(updatedSpans.ToImmutableAndClear());
}

private static BlockSpan UpdateBlockSpan(BlockSpan blockSpan, in BlockStructureOptions options)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#nullable disable

using System;
using System.Collections.Immutable;
using System.Threading.Tasks;
Expand All @@ -30,7 +28,7 @@ protected AbstractBlockStructureProvider(
_triviaProviderMap = defaultTriviaOutlinerMap;
}

public override void ProvideBlockStructure(BlockStructureContext context)
public override void ProvideBlockStructure(in BlockStructureContext context)
{
try
{
Expand All @@ -39,8 +37,9 @@ public override void ProvideBlockStructure(BlockStructureContext context)
BlockSpanCollector.CollectBlockSpans(
syntaxRoot, context.Options, _nodeProviderMap, _triviaProviderMap, ref spans.AsRef(), context.CancellationToken);

context.Spans.EnsureCapacity(context.Spans.Count + spans.Count);
foreach (var span in spans)
context.AddBlockSpan(span);
context.Spans.Add(span);
}
catch (Exception e) when (FatalError.ReportAndPropagateUnlessCanceled(e))
{
Expand Down

0 comments on commit 7a43937

Please sign in to comment.