From 108c5f643e5a223d2a4e75873bc7fefbb02c2d2c Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Tue, 18 May 2021 13:35:05 +0200 Subject: [PATCH] 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. --- .../CSharp/Syntax/CSharpTokenNode.cs | 17 ++++++-- .../CSharp/Syntax/TokenRole.cs | 43 +------------------ 2 files changed, 15 insertions(+), 45 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/CSharpTokenNode.cs b/ICSharpCode.Decompiler/CSharp/Syntax/CSharpTokenNode.cs index 5cd2a5d02..6bbf8a546 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/CSharpTokenNode.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/CSharpTokenNode.cs @@ -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 { 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 } } } - diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/TokenRole.cs b/ICSharpCode.Decompiler/CSharp/Syntax/TokenRole.cs index 233637d6b..0dbafa00c 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/TokenRole.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/TokenRole.cs @@ -1,5 +1,3 @@ -using System.Collections.Generic; - namespace ICSharpCode.Decompiler.CSharp.Syntax { /// @@ -7,57 +5,20 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// public sealed class TokenRole : Role { - internal readonly static List Tokens = new List(); - internal readonly static List TokenLengths = new List(); - internal readonly uint TokenIndex; - - static TokenRole() - { - // null token - Tokens.Add(""); - TokenLengths.Add(0); - } - /// /// Gets the token as string. Note that the token Name and Token value may differ. /// - public string Token { - get; - private set; - } + public string Token { get; } /// /// Gets the char length of the token. /// - 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); - } } } } -