diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyWriter.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyWriter.cs index 3a1542ec41df399cc946ac65b07ba3613a6a5887..e350eed6eddaa10eca49cbb40a5c57344ac16e24 100644 --- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyWriter.cs +++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyWriter.cs @@ -202,8 +202,8 @@ private void WriteSpace() _stringBuilder.Append(' '); } - internal void WriteFormatVersion() - => WriteIntegerRaw_DoNotCallDirectly(FormatVersion); + internal void WriteFormatVersion(int version) + => WriteIntegerRaw_DoNotCallDirectly(version); internal void WriteInteger(int value) { diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.cs index 05d47e4cdca72c7be10ba6741e434f3aa42241cf..5ed916ed0c90e60a5b917f1e433f7cb9bde2ca62 100644 --- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.cs +++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.cs @@ -90,7 +90,7 @@ internal partial struct SymbolKey /// out a SymbolKey from a previous version of Roslyn and then attempt to use it in a /// newer version where the encoding has changed. /// - private const int FormatVersion = 1; + internal const int FormatVersion = 1; private readonly string _symbolKeyData; @@ -143,9 +143,13 @@ internal static IEqualityComparer GetComparer(bool ignoreCase = false } internal static string CreateString(ISymbol symbol, CancellationToken cancellationToken = default) + => CreateStringWorker(FormatVersion, symbol, cancellationToken); + + // Internal for testing purposes. + internal static string CreateStringWorker(int version, ISymbol symbol, CancellationToken cancellationToken = default) { using var writer = SymbolKeyWriter.GetWriter(cancellationToken); - writer.WriteFormatVersion(); + writer.WriteFormatVersion(version); writer.WriteSymbolKey(symbol); return writer.CreateKey(); } diff --git a/src/Workspaces/CoreTest/SymbolKeyTests.cs b/src/Workspaces/CoreTest/SymbolKeyTests.cs index 9e404f6509c48cfc34f26af656062ec699791bbe..32637643fc97a242470b046216aabe7f1a6e9c61 100644 --- a/src/Workspaces/CoreTest/SymbolKeyTests.cs +++ b/src/Workspaces/CoreTest/SymbolKeyTests.cs @@ -17,6 +17,61 @@ namespace Microsoft.CodeAnalysis.UnitTests [UseExportProvider] public class SymbolKeyTests : TestBase { + [Fact] + public void TestVersionMismatch() + { + var source = @" + +public class C +{ + public class B { }; + public delegate int D(int v); + + public int F; + public B F2; + public int P { get; set;} + public B P2 { get; set; } + public void M() { }; + public void M(int a) { }; + public void M(int a, string b) { }; + public void M(string a, int b) { }; + public void M(B b) { }; + public int M2() { return 0; } + public int M2(int a) { return 0; } + public int M2(int a, string b) { return 0; } + public int M2(string a, int b) { return 0; } + public B M3() { return default(B); } + public int this[int index] { get { return 0; } } + public int this[int a, int b] { get { return 0; } } + public B this[B b] { get { return b; } } + public event D E; + public event D E2 { add; remove; } +} +"; + var compilation = GetCompilation(source, LanguageNames.CSharp); + foreach (var symbol in GetDeclaredSymbols(compilation)) + { + Test(symbol, compilation); + } + + return; + + static void Test(ISymbol symbol, Compilation compilation) + { + TestVersion(symbol, compilation, SymbolKey.FormatVersion - 1); + TestVersion(symbol, compilation, SymbolKey.FormatVersion + 1); + TestVersion(symbol, compilation, int.MaxValue); + } + + static void TestVersion(ISymbol symbol, Compilation compilation, int version) + { + var id = SymbolKey.CreateStringWorker(version, symbol); + Assert.NotNull(id); + var found = SymbolKey.ResolveString(id, compilation).GetAnySymbol(); + Assert.Null(found); + } + } + [Fact] public void TestMemberDeclarations() {