Browse Source

Fix #2413: Avoid global state in `TokenRole`.

We can already compactly store a `TokenRole` via the index+lookup in the `Role` base class.
The lookup in the base class is thread-safe; the one removed here was not.
pull/2418/head
Daniel Grunwald 4 years ago
parent
commit
108c5f643e
  1. 17
      ICSharpCode.Decompiler/CSharp/Syntax/CSharpTokenNode.cs
  2. 43
      ICSharpCode.Decompiler/CSharp/Syntax/TokenRole.cs

17
ICSharpCode.Decompiler/CSharp/Syntax/CSharpTokenNode.cs

@ -85,7 +85,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -85,7 +85,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
int TokenLength {
get {
return TokenRole.TokenLengths[(int)(this.flags >> AstNodeFlagsUsedBits)];
uint tokenRoleIndex = (this.flags >> AstNodeFlagsUsedBits);
if (Role.GetByIndex(tokenRoleIndex) is TokenRole r)
{
return r.Length;
}
return 0;
}
}
@ -99,12 +104,17 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -99,12 +104,17 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{
this.startLocation = location;
if (role != null)
this.flags |= role.TokenIndex << AstNodeFlagsUsedBits;
this.flags |= role.Index << AstNodeFlagsUsedBits;
}
public override string ToString(CSharpFormattingOptions formattingOptions)
{
return TokenRole.Tokens[(int)(this.flags >> AstNodeFlagsUsedBits)];
uint tokenRoleIndex = (this.flags >> AstNodeFlagsUsedBits);
if (Role.GetByIndex(tokenRoleIndex) is TokenRole r)
{
return r.Token;
}
return string.Empty;
}
public override void AcceptVisitor(IAstVisitor visitor)
@ -129,4 +139,3 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -129,4 +139,3 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
}
}

43
ICSharpCode.Decompiler/CSharp/Syntax/TokenRole.cs

@ -1,5 +1,3 @@ @@ -1,5 +1,3 @@
using System.Collections.Generic;
namespace ICSharpCode.Decompiler.CSharp.Syntax
{
/// <summary>
@ -7,57 +5,20 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -7,57 +5,20 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
/// </summary>
public sealed class TokenRole : Role<CSharpTokenNode>
{
internal readonly static List<string> Tokens = new List<string>();
internal readonly static List<int> TokenLengths = new List<int>();
internal readonly uint TokenIndex;
static TokenRole()
{
// null token
Tokens.Add("");
TokenLengths.Add(0);
}
/// <summary>
/// Gets the token as string. Note that the token Name and Token value may differ.
/// </summary>
public string Token {
get;
private set;
}
public string Token { get; }
/// <summary>
/// Gets the char length of the token.
/// </summary>
public int Length {
get;
private set;
}
public int Length { get; }
public TokenRole(string token) : base(token, CSharpTokenNode.Null)
{
this.Token = token;
this.Length = token.Length;
bool found = false;
for (int i = 0; i < Tokens.Count; i++)
{
var existingToken = Tokens[i];
if (existingToken == token)
{
TokenIndex = (uint)i;
found = true;
break;
}
}
if (!found)
{
TokenIndex = (uint)Tokens.Count;
Tokens.Add(token);
TokenLengths.Add(this.Length);
}
}
}
}

Loading…
Cancel
Save