Skip to content

Commit

Permalink
Expand the SyntaxTokenCache to contain more than just whitespace tokens.
Browse files Browse the repository at this point in the history
  • Loading branch information
ToddGrun committed Jun 8, 2020
1 parent f56cad0 commit 837c639
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ internal static partial class SyntaxFactory
{
internal static SyntaxToken Token(SyntaxKind kind, string content, params RazorDiagnostic[] diagnostics)
{
if (kind == SyntaxKind.Whitespace && diagnostics.Length == 0)
if (SyntaxTokenCache.CanBeCached(kind, diagnostics))
{
return WhitespaceTokenCache.GetToken(content);
return SyntaxTokenCache.GetCachedToken(kind, content);
}

return new SyntaxToken(kind, content, diagnostics);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// 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 Microsoft.Extensions.Internal;

namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
{
// Simplified version of Roslyn's SyntaxNodeCache
internal static class SyntaxTokenCache
{
private const int CacheSizeBits = 16;
private const int CacheSize = 1 << CacheSizeBits;
private const int CacheMask = CacheSize - 1;
private static readonly Entry[] s_cache = new Entry[CacheSize];

private struct Entry
{
public int Hash { get; }
public SyntaxToken Token { get; }

internal Entry(int hash, SyntaxToken token)
{
Hash = hash;
Token = token;
}
}

public static bool CanBeCached(SyntaxKind kind, params RazorDiagnostic[] diagnostics)
{
if (diagnostics.Length == 0)
{
switch (kind)
{
case SyntaxKind.CharacterLiteral:
case SyntaxKind.Dot:
case SyntaxKind.Identifier:
case SyntaxKind.IntegerLiteral:
case SyntaxKind.Keyword:
case SyntaxKind.NewLine:
case SyntaxKind.RazorCommentStar:
case SyntaxKind.RazorCommentTransition:
case SyntaxKind.StringLiteral:
case SyntaxKind.Transition:
case SyntaxKind.Whitespace:
return true;
}
}

return false;
}

public static SyntaxToken GetCachedToken(SyntaxKind kind, string content)
{
var hash = (kind, content).GetHashCode();

// Allow the upper 16 bits to contribute to the index
var indexableHash = hash ^ (hash >> 16);

var idx = indexableHash & CacheMask;
var e = s_cache[idx];

if (e.Hash == hash && e.Token.Kind == kind && e.Token.Content == content)
{
return e.Token;
}

var token = new SyntaxToken(kind, content, Array.Empty<RazorDiagnostic>());
s_cache[idx] = new Entry(hash, token);

return token;
}
}
}

This file was deleted.

0 comments on commit 837c639

Please sign in to comment.