提交 a014a190 编写于 作者: C CyrusNajmabadi

Switch to a struct with a cached hashcode.

上级 c6f714da
......@@ -80,7 +80,7 @@ internal static ISymbol ResolveSymbol(ISymbol originalSymbol, Compilation target
// Verify that serialization works.
var serialized = sid.ToString();
var deserialized = SymbolKey.FromString(serialized);
var deserialized = new SymbolKey(serialized);
var comparer = SymbolKey.GetComparer(ignoreCase: false, ignoreAssemblyKeys: false);
Assert.True(comparer.Equals(sid, deserialized));
......
......@@ -154,7 +154,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.NavigationBar
Assert.Equal(expectedItem.Grayed, actualItem.Grayed)
If expectedItem.HasNavigationSymbolId Then
Assert.True(DirectCast(actualItem, NavigationBarSymbolItem).NavigationSymbolId IsNot Nothing)
' Assert.True(DirectCast(actualItem, NavigationBarSymbolItem).NavigationSymbolId IsNot Nothing)
Assert.Equal(expectedItem.HasNavigationSymbolId, DirectCast(actualItem, NavigationBarSymbolItem).NavigationSymbolIndex.HasValue)
Else
Assert.True(TypeOf actualItem IsNot NavigationBarSymbolItem)
......
......@@ -73,7 +73,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.SymbolId
' Verify that serialization works.
Dim serialized = sid.ToString()
Dim deserialized = SymbolKey.FromString(serialized)
Dim deserialized = New SymbolKey(serialized)
Dim comparer = SymbolKey.GetComparer(ignoreCase:=False, ignoreAssemblyKeys:=False)
Assert.True(comparer.Equals(sid, deserialized))
......
......@@ -10,7 +10,7 @@ internal abstract partial class AbstractSignatureHelpProvider
{
internal class SymbolKeySignatureHelpItem : SignatureHelpItem, IEquatable<SymbolKeySignatureHelpItem>
{
public SymbolKey SymbolKey { get; }
public SymbolKey? SymbolKey { get; }
public SymbolKeySignatureHelpItem(
ISymbol symbol,
......@@ -22,7 +22,7 @@ internal class SymbolKeySignatureHelpItem : SignatureHelpItem, IEquatable<Symbol
IEnumerable<SignatureHelpParameter> parameters,
IEnumerable<SymbolDisplayPart> descriptionParts) : base(isVariadic, documentationFactory, prefixParts, separatorParts, suffixParts, parameters, descriptionParts)
{
this.SymbolKey = symbol == null ? null : symbol.GetSymbolKey();
this.SymbolKey = symbol?.GetSymbolKey();
}
public override bool Equals(object obj)
......@@ -33,9 +33,9 @@ public override bool Equals(object obj)
public bool Equals(SymbolKeySignatureHelpItem obj)
{
return ReferenceEquals(this, obj) ||
(obj != null &&
this.SymbolKey != null &&
SymbolKey.GetComparer(ignoreCase: false, ignoreAssemblyKeys: false).Equals(this.SymbolKey, obj.SymbolKey));
(obj?.SymbolKey != null &&
this.SymbolKey != null &&
CodeAnalysis.SymbolKey.GetComparer(ignoreCase: false, ignoreAssemblyKeys: false).Equals(this.SymbolKey.Value, obj.SymbolKey.Value));
}
public override int GetHashCode()
......@@ -45,8 +45,8 @@ public override int GetHashCode()
return 0;
}
var comparer = SymbolKey.GetComparer(ignoreCase: false, ignoreAssemblyKeys: false);
return comparer.GetHashCode(this.SymbolKey);
var comparer = CodeAnalysis.SymbolKey.GetComparer(ignoreCase: false, ignoreAssemblyKeys: false);
return comparer.GetHashCode(this.SymbolKey.Value);
}
}
}
......
......@@ -192,8 +192,7 @@ where part.Symbol.IsNormalAnonymousType()
continue;
}
var expectedSymbol = symbolKey.Resolve(compilation, ignoreAssemblyKey: true, cancellationToken: cancellationToken).Symbol;
var expectedSymbol = symbolKey.Value.Resolve(compilation, ignoreAssemblyKey: true, cancellationToken: cancellationToken).Symbol;
if (expectedSymbol == null)
{
finalItems.Add(item);
......@@ -231,7 +230,7 @@ where part.Symbol.IsNormalAnonymousType()
if (!related.Item1.GetLanguageService<ISyntaxFactsService>().IsInInactiveRegion(syntaxTree, position, cancellationToken))
{
var relatedSemanticModel = await related.Item1.GetSemanticModelForSpanAsync(new TextSpan(position, 0), cancellationToken).ConfigureAwait(false);
var symbolSet = related.Item2.Select(s => ((SymbolKeySignatureHelpItem)s).SymbolKey.Resolve(relatedSemanticModel.Compilation, cancellationToken: cancellationToken).Symbol)
var symbolSet = related.Item2.Select(s => ((SymbolKeySignatureHelpItem)s).SymbolKey?.Resolve(relatedSemanticModel.Compilation, cancellationToken: cancellationToken).Symbol)
.WhereNotNull()
.ToSet(SymbolEquivalenceComparer.IgnoreAssembliesInstance);
resultSets.Add(Tuple.Create(related.Item1.Project.Id, symbolSet));
......
......@@ -115,8 +115,8 @@ private async Task PopulateMapsForSymbolInputNodeAsync(GraphNode inputNode)
_nodeToContextProjectMap.Add(inputNode, project);
var compilation = await project.GetCompilationAsync(_cancellationToken).ConfigureAwait(false);
var symbolId = inputNode[RoslynGraphProperties.SymbolId] as SymbolKey;
var symbol = symbolId.Resolve(compilation).Symbol;
var symbolId = (SymbolKey?)inputNode[RoslynGraphProperties.SymbolId];
var symbol = symbolId.Value.Resolve(compilation).Symbol;
if (symbol != null)
{
_nodeToSymbolMap.Add(inputNode, symbol);
......@@ -205,7 +205,7 @@ public async Task<GraphNode> AddNodeForSymbolAsync(ISymbol symbol, Project conte
{
GraphNode node = await GetOrCreateNodeAsync(_graph, symbol, _solution, _cancellationToken).ConfigureAwait(false);
node[RoslynGraphProperties.SymbolId] = symbol.GetSymbolKey();
node[RoslynGraphProperties.SymbolId] = (SymbolKey?)symbol.GetSymbolKey();
node[RoslynGraphProperties.ContextProjectId] = GetContextProjectId(contextProject, symbol);
node[RoslynGraphProperties.ExplicitInterfaceImplementations] = symbol.ExplicitInterfaceImplementations().Select(s => s.GetSymbolKey()).ToList();
node[RoslynGraphProperties.DeclaredAccessibility] = symbol.DeclaredAccessibility;
......
......@@ -37,7 +37,7 @@ public void NavigateTo(GraphObject graphObject)
}
var projectId = graphNode.GetValue<ProjectId>(RoslynGraphProperties.ContextProjectId);
var symbolId = graphNode.GetValue<SymbolKey>(RoslynGraphProperties.SymbolId);
var symbolId = graphNode.GetValue<SymbolKey?>(RoslynGraphProperties.SymbolId);
if (projectId != null)
{
......@@ -81,7 +81,7 @@ public void NavigateTo(GraphObject graphObject)
}
}
private void NavigateOnForegroundThread(SourceLocation sourceLocation, SymbolKey symbolId, Project project, Document document)
private void NavigateOnForegroundThread(SourceLocation sourceLocation, SymbolKey? symbolId, Project project, Document document)
{
AssertIsForeground();
......@@ -89,7 +89,7 @@ private void NavigateOnForegroundThread(SourceLocation sourceLocation, SymbolKey
if (symbolId != null)
{
var symbolNavigationService = _workspace.Services.GetService<ISymbolNavigationService>();
var symbol = symbolId.Resolve(project.GetCompilationAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None)).Symbol;
var symbol = symbolId.Value.Resolve(project.GetCompilationAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None)).Symbol;
// Do not allow third party navigation to types or constructors
if (symbol != null &&
......
......@@ -350,7 +350,7 @@ private bool IsAnyTypeKind(GraphNode node, params TypeKind[] typeKinds)
// TODO: The check here is to see if the SymbolId property exists on the node
// and if so, that's been created by us. However, eventually we'll want to extend
// this to other scenarios where C#\VB nodes that aren't created by us are passed in.
if (graphNode.GetValue<SymbolKey>(RoslynGraphProperties.SymbolId) == null)
if (graphNode.GetValue<SymbolKey?>(RoslynGraphProperties.SymbolId) == null)
{
return null;
}
......
......@@ -99,7 +99,7 @@ static RoslynGraphProperties()
SymbolId = Schema.Properties.AddNewProperty(
id: "SymbolId",
dataType: typeof(SymbolKey),
dataType: typeof(SymbolKey?),
callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable));
ContextProjectId = Schema.Properties.AddNewProperty(
......
......@@ -273,11 +273,6 @@ public ImmutableArray<SymbolDisplayPart> ToMinimalDisplayParts(SemanticModel sem
throw new NotImplementedException();
}
public SymbolKey GetSymbolId()
{
return null;
}
public virtual string MetadataName
{
get
......
......@@ -306,7 +306,7 @@ private static async Task AddNonSubmissionDependentProjectsAsync(IAssemblySymbol
var internalsVisibleToMap = CreateInternalsVisibleToMap(sourceAssembly);
SymbolKey sourceAssemblySymbolKey = null;
SymbolKey? sourceAssemblySymbolKey = null;
// TODO(cyrusn): What about error tolerance situations. Do we maybe want to search
// transitive dependencies as well? Even if the code wouldn't compile, they may be
......@@ -328,7 +328,7 @@ private static async Task AddNonSubmissionDependentProjectsAsync(IAssemblySymbol
if (sourceAssembly.Language != targetAssembly.Language)
{
sourceAssemblySymbolKey = sourceAssemblySymbolKey ?? sourceAssembly.GetSymbolKey();
var sourceAssemblyInTargetCompilation = sourceAssemblySymbolKey.Resolve(compilation, cancellationToken: cancellationToken).Symbol as IAssemblySymbol;
var sourceAssemblyInTargetCompilation = sourceAssemblySymbolKey.Value.Resolve(compilation, cancellationToken: cancellationToken).Symbol as IAssemblySymbol;
if (sourceAssemblyInTargetCompilation != null)
{
......
......@@ -5,11 +5,11 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class AliasSymbolKey
{
public static void Create(IAliasSymbol symbol, Visitor visitor)
public static void Create(IAliasSymbol symbol, SymbolKeyWriter visitor)
{
visitor.WriteString(symbol.Name);
visitor.WriteSymbolKey(symbol.Target);
......
......@@ -5,11 +5,11 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class ArrayTypeSymbolKey
{
public static void Create(IArrayTypeSymbol symbol, Visitor visitor)
public static void Create(IArrayTypeSymbol symbol, SymbolKeyWriter visitor)
{
visitor.WriteSymbolKey(symbol.ElementType);
visitor.WriteInteger(symbol.Rank);
......
......@@ -5,11 +5,11 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class AssemblySymbolKey
{
public static void Create(IAssemblySymbol symbol, Visitor visitor)
public static void Create(IAssemblySymbol symbol, SymbolKeyWriter visitor)
{
// If the format of this ever changed, then it's necessary to fixup the
// SymbolKeyComparer.RemoveAssemblyKeys function.
......@@ -19,9 +19,10 @@ public static void Create(IAssemblySymbol symbol, Visitor visitor)
public static int GetHashCode(GetHashCodeReader reader)
{
var value = reader.ReadString();
// isCaseSensitive doesn't apply here as AssemblyIdentity is always case
// insensitive.
return reader.Options.IgnoreAssemblyKey ? 1 : value;
// Hash all assembly keys to the same bucket. That way we're a uniform
// hash regardless if clients care about assembly IDs or not.
return 1;
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
......
......@@ -7,11 +7,11 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class BodyLevelSymbolKey
{
public static void Create(ISymbol symbol, Visitor visitor)
public static void Create(ISymbol symbol, SymbolKeyWriter visitor)
{
var containingSymbol = symbol.ContainingSymbol;
......
......@@ -4,7 +4,7 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private struct ComparisonOptions
{
......
......@@ -2,13 +2,13 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class DynamicTypeSymbolKey
{
private static readonly object instance = new object();
public static void Create(Visitor visitor)
public static void Create(SymbolKeyWriter visitor)
{
}
......
......@@ -7,11 +7,11 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class ErrorTypeSymbolKey
{
public static void Create(INamedTypeSymbol symbol, Visitor visitor)
public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor)
{
visitor.WriteString(symbol.Name);
visitor.WriteSymbolKey(symbol.ContainingSymbol as INamespaceOrTypeSymbol);
......
......@@ -5,11 +5,11 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class EventSymbolKey
{
public static void Create(IEventSymbol symbol, Visitor visitor)
public static void Create(IEventSymbol symbol, SymbolKeyWriter visitor)
{
visitor.WriteString(symbol.MetadataName);
visitor.WriteSymbolKey(symbol.ContainingType);
......
......@@ -5,11 +5,11 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class FieldSymbolKey
{
public static void Create(IFieldSymbol symbol, Visitor visitor)
public static void Create(IFieldSymbol symbol, SymbolKeyWriter visitor)
{
visitor.WriteString(symbol.MetadataName);
visitor.WriteSymbolKey(symbol.ContainingType);
......
......@@ -8,11 +8,11 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class ReducedExtensionMethodSymbolKey
{
public static void Create(IMethodSymbol symbol, Visitor visitor)
public static void Create(IMethodSymbol symbol, SymbolKeyWriter visitor)
{
Debug.Assert(symbol.Equals(symbol.ConstructedFrom));
......@@ -41,11 +41,11 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
}
}
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class ConstructedMethodSymbolKey
{
public static void Create(IMethodSymbol symbol, Visitor visitor)
public static void Create(IMethodSymbol symbol, SymbolKeyWriter visitor)
{
visitor.WriteSymbolKey(symbol.ConstructedFrom);
visitor.WriteSymbolKeyArray(symbol.TypeArguments);
......@@ -81,11 +81,11 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
}
}
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class MethodSymbolKey
{
public static void Create(IMethodSymbol symbol, Visitor visitor)
public static void Create(IMethodSymbol symbol, SymbolKeyWriter visitor)
{
Debug.Assert(symbol.Equals(symbol.ConstructedFrom));
......
......@@ -5,11 +5,11 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class ModuleSymbolKey
{
public static void Create(IModuleSymbol symbol, Visitor visitor)
public static void Create(IModuleSymbol symbol, SymbolKeyWriter visitor)
{
visitor.WriteSymbolKey(symbol.ContainingSymbol);
}
......
......@@ -7,11 +7,11 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class NamedTypeSymbolKey
{
public static void Create(INamedTypeSymbol symbol, Visitor visitor)
public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor)
{
visitor.WriteString(symbol.MetadataName);
visitor.WriteSymbolKey(symbol.ContainingSymbol);
......
......@@ -10,7 +10,7 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class NamespaceSymbolKey
{
......@@ -22,7 +22,7 @@ private static class NamespaceSymbolKey
// 4) The SymbolId for the containing namespace symbol if this is not a global
// namespace.
public static void Create(INamespaceSymbol symbol, Visitor visitor)
public static void Create(INamespaceSymbol symbol, SymbolKeyWriter visitor)
{
visitor.WriteString(symbol.MetadataName);
......
......@@ -6,11 +6,11 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class ParameterSymbolKey
{
public static void Create(IParameterSymbol symbol, Visitor visitor)
public static void Create(IParameterSymbol symbol, SymbolKeyWriter visitor)
{
visitor.WriteString(symbol.MetadataName);
visitor.WriteSymbolKey(symbol.ContainingSymbol);
......
......@@ -5,11 +5,11 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class PointerTypeSymbolKey
{
public static void Create(IPointerTypeSymbol symbol, Visitor visitor)
public static void Create(IPointerTypeSymbol symbol, SymbolKeyWriter visitor)
{
visitor.WriteSymbolKey(symbol.PointedAtType);
}
......
......@@ -5,11 +5,11 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class PropertySymbolKey
{
public static void Create(IPropertySymbol symbol, Visitor visitor)
public static void Create(IPropertySymbol symbol, SymbolKeyWriter visitor)
{
visitor.WriteString(symbol.MetadataName);
visitor.WriteSymbolKey(symbol.ContainingSymbol);
......
......@@ -8,7 +8,7 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private class SymbolKeyComparer : IEqualityComparer<SymbolKey>
{
......@@ -21,16 +21,6 @@ private SymbolKeyComparer(ComparisonOptions options)
public bool Equals(SymbolKey x, SymbolKey y)
{
if (x == y)
{
return true;
}
if (x == null || y == null)
{
return false;
}
var comparer = _options.IgnoreCase
? StringComparer.OrdinalIgnoreCase
: StringComparer.Ordinal;
......@@ -60,12 +50,7 @@ private string RemoveAssemblyKeys(string data)
public int GetHashCode(SymbolKey obj)
{
if (obj == null)
{
return 0;
}
return SymbolKey.GetHashCode(obj, _options);
return obj.GetHashCode();
}
public static IEqualityComparer<SymbolKey> GetComparer(bool ignoreCase, bool ignoreAssemblyKey)
......
......@@ -12,7 +12,7 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private abstract class Reader<TStringResult> : IDisposable
{
......@@ -274,51 +274,39 @@ private class GetHashCodeReader : Reader<int, int>
private static readonly ObjectPool<GetHashCodeReader> s_pool =
new ObjectPool<GetHashCodeReader>(() => new GetHashCodeReader());
public ComparisonOptions Options { get; private set; }
private GetHashCodeReader()
{
}
public static GetHashCodeReader GetReader(string data, ComparisonOptions options)
public static GetHashCodeReader GetReader(string data)
{
var reader = s_pool.Allocate();
reader.Initialize(data, options);
reader.Initialize(data);
return reader;
}
public override void Dispose()
{
base.Dispose();
Options = default(ComparisonOptions);
s_pool.Free(this);
}
private void Initialize(string data, ComparisonOptions options)
private void Initialize(string data)
{
base.Initialize(data, CancellationToken.None);
Options = options;
}
protected override int CreateResultForString(int start, int end, bool hasEmbeddedQuote)
{
var result = 1;
if (Options.IgnoreCase)
{
for (var i = start; i < end; i++)
{
result = Hash.Combine((int)char.ToLower(Data[i]), result);
}
}
else
// Note: we hash all strings to lowercase. It will mean more collisions, but
// it provides a uniform hashing strategy for all keys.
for (var i = start; i < end; i++)
{
for (var i = start; i < end; i++)
{
result = Hash.Combine((int)Data[i], result);
}
result = Hash.Combine((int)char.ToLower(Data[i]), result);
}
return result;
}
......
......@@ -10,7 +10,7 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private enum SymbolKeyType
{
......@@ -41,10 +41,10 @@ private enum SymbolKeyType
TypeParameterOrdinal = '@',
}
private class Visitor : SymbolVisitor<object>, IDisposable
private class SymbolKeyWriter : SymbolVisitor<object>, IDisposable
{
private static readonly ObjectPool<Visitor> s_visitorPool =
new ObjectPool<Visitor>(() => new Visitor());
private static readonly ObjectPool<SymbolKeyWriter> s_writerPool =
new ObjectPool<SymbolKeyWriter>(() => new SymbolKeyWriter());
private readonly Action<ISymbol> _writeSymbolKey;
private readonly Action<string> _writeString;
......@@ -61,7 +61,7 @@ private class Visitor : SymbolVisitor<object>, IDisposable
internal int _nestingCount;
private int _nextId;
private Visitor()
private SymbolKeyWriter()
{
_writeSymbolKey = WriteSymbolKey;
_writeString = WriteString;
......@@ -79,12 +79,12 @@ public void Dispose()
_nextId = 0;
// Place us back in the pool for future use.
s_visitorPool.Free(this);
s_writerPool.Free(this);
}
public static Visitor GetVisitor(Compilation compilation, CancellationToken cancellationToken)
public static SymbolKeyWriter GetWriter(Compilation compilation, CancellationToken cancellationToken)
{
var visitor = s_visitorPool.Allocate();
var visitor = s_writerPool.Allocate();
visitor.Initialize(compilation, cancellationToken);
return visitor;
}
......
......@@ -6,11 +6,11 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class TupleTypeSymbolKey
{
public static void Create(INamedTypeSymbol symbol, Visitor visitor)
public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor)
{
Debug.Assert(symbol.IsTupleType);
visitor.WriteSymbolKey(symbol.TupleUnderlyingType);
......
......@@ -4,11 +4,11 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class TypeParameterOrdinalSymbolKey
{
public static void Create(ITypeParameterSymbol symbol, Visitor visitor)
public static void Create(ITypeParameterSymbol symbol, SymbolKeyWriter visitor)
{
Debug.Assert(visitor.WritingSignature);
Debug.Assert(symbol.TypeParameterKind == TypeParameterKind.Method);
......
......@@ -5,11 +5,11 @@
namespace Microsoft.CodeAnalysis
{
internal partial class SymbolKey
internal partial struct SymbolKey
{
private static class TypeParameterSymbolKey
{
public static void Create(ITypeParameterSymbol symbol, Visitor visitor)
public static void Create(ITypeParameterSymbol symbol, SymbolKeyWriter visitor)
{
visitor.WriteString(symbol.MetadataName);
visitor.WriteSymbolKey(symbol.ContainingSymbol);
......
......@@ -76,25 +76,26 @@ namespace Microsoft.CodeAnalysis
/// </para>
/// </para>
/// </summary>
internal partial class SymbolKey
internal partial struct SymbolKey
{
private readonly static Func<ITypeSymbol, bool> s_typeIsNull = t => t == null;
private readonly string _symbolKeyData;
private readonly int _hashCode;
private SymbolKey(string symbolKeyData)
public SymbolKey(string symbolKeyData)
{
if (symbolKeyData == null)
{
throw new ArgumentNullException();
}
_symbolKeyData = symbolKeyData;
}
public static SymbolKey FromString(string data)
{
return new SymbolKey(data);
using (var reader = GetHashCodeReader.GetReader(_symbolKeyData))
{
_hashCode = reader.ReadFirstSymbolKey();
}
}
public static IEqualityComparer<SymbolKey> GetComparer(bool ignoreCase, bool ignoreAssemblyKeys)
......@@ -109,14 +110,6 @@ public static IEqualityComparer<SymbolKey> GetComparer(bool ignoreCase, bool ign
return reader.RemoveAssemblySymbolKeys();
};
private static int GetHashCode(SymbolKey key, ComparisonOptions options)
{
using (var reader = GetHashCodeReader.GetReader(key._symbolKeyData, options))
{
return reader.ReadFirstSymbolKey();
}
}
public static SymbolKeyResolution Resolve(
string symbolKey, Compilation compilation,
bool ignoreAssemblyKey = false, CancellationToken cancellationToken = default(CancellationToken))
......@@ -136,10 +129,10 @@ public static string ToString(ISymbol symbol, CancellationToken cancellationToke
{
var compilation = (symbol.ContainingAssembly as ISourceAssemblySymbol)?.Compilation;
using (var visitor = Visitor.GetVisitor(compilation, cancellationToken))
using (var writer = SymbolKeyWriter.GetWriter(compilation, cancellationToken))
{
visitor.WriteFirstSymbolKey(symbol);
return visitor.CreateKey();
writer.WriteFirstSymbolKey(symbol);
return writer.CreateKey();
}
}
......@@ -256,5 +249,10 @@ private static TSymbol GetFirstSymbol<TSymbol>(SymbolKeyResolution resolution)
return true;
}
public override int GetHashCode()
{
return _hashCode;
}
}
}
\ No newline at end of file
......@@ -445,7 +445,7 @@
<Compile Include="SymbolId\SymbolKey.FieldSymbolKey.cs" />
<Compile Include="SymbolId\SymbolKey.DynamicTypeSymbolKey.cs" />
<Compile Include="SymbolId\SymbolKey.ArrayTypeSymbolKey.cs" />
<Compile Include="SymbolId\SymbolKey.Visitor.cs" />
<Compile Include="SymbolId\SymbolKey.SymbolKeyWriter.cs" />
<Compile Include="SymbolId\SymbolKey.cs" />
<Compile Include="SymbolSearch\ISymbolSearchService.cs" />
<Compile Include="FindSymbols\SymbolTree\ISymbolTreeInfoCacheService.cs" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册