Skip to content

Commit 67b5515

Browse files
Compiler: Avoid allocating strings in the RazorHtmlWriter (#11975)
This pull request is essentially a rewrite of `RazorHtmlWriter` with the following changes: - Simply span tracking for source mappings. - Avoid allocating strings when writing whitespace to the `CodeWriter` and reduce the number of writes. - Avoid allocating strings when writing C# placeholder content (i.e. `~~~` and `/*~~~~~~~*/`). - Avoid allocating delegates to base visitor methods. - Fix a bug this change uncovered in the `CodeWriter.Reader.Read(char[], int, int)` implementation that can cause the `SourceText` produced to be one character shorter than expected. I recommend reviewing commit-by-commit. ---- CI Build: https://dev.azure.com/dnceng/internal/_build/results?buildId=2736836&view=results Test Insertion: https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/646317 Toolset Run: https://dev.azure.com/dnceng/internal/_build/results?buildId=2736837&view=results
2 parents b19eff2 + 89efed2 commit 67b5515

File tree

3 files changed

+279
-202
lines changed

3 files changed

+279
-202
lines changed

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/CodeWriter.cs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ public override int Read(char[] buffer, int index, int count)
415415

416416
if (_page is null)
417417
{
418-
return -1;
418+
return 0;
419419
}
420420

421421
var destination = buffer.AsSpan(index, count);
@@ -435,6 +435,12 @@ public override int Read(char[] buffer, int index, int count)
435435

436436
foreach (var chunk in chunks)
437437
{
438+
if (destination.IsEmpty)
439+
{
440+
// If we have no more space in the destination, we're done.
441+
break;
442+
}
443+
438444
var source = chunk.Span;
439445

440446
// Slice if the first chunk is partial. Note that this only occurs for the first chunk.
@@ -461,16 +467,15 @@ public override int Read(char[] buffer, int index, int count)
461467
charIndex = 0;
462468
}
463469

470+
if (source.IsEmpty)
471+
{
472+
continue;
473+
}
474+
464475
source.CopyTo(destination);
465476
destination = destination[source.Length..];
466477

467478
charsWritten += source.Length;
468-
469-
// Break if we are done writing. chunkIndex and charIndex should have their correct values at this point.
470-
if (destination.IsEmpty)
471-
{
472-
break;
473-
}
474479
}
475480

476481
if (destination.IsEmpty)
@@ -497,6 +502,8 @@ public override int Read(char[] buffer, int index, int count)
497502
_charIndex = -1;
498503
}
499504

505+
_remainingLength -= charsWritten;
506+
500507
return charsWritten;
501508
}
502509

@@ -551,6 +558,7 @@ public override string ReadToEnd()
551558
_page = null;
552559
_chunkIndex = -1;
553560
_charIndex = 1;
561+
_remainingLength = 0;
554562

555563
return result;
556564
}

0 commit comments

Comments
 (0)