From b4c9c9e6c5399dec4016c7e17c3dce80d6880413 Mon Sep 17 00:00:00 2001 From: CyrusNajmabadi Date: Wed, 10 May 2017 15:10:29 -0700 Subject: [PATCH] Add more contract guarantees --- .../SymbolTree/SymbolTreeInfo_Metadata.cs | 4 +++- .../SymbolTreeInfo_Serialization.cs | 23 +++---------------- .../SymbolTree/SymbolTreeInfo_Source.cs | 14 ++++++++--- 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Metadata.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Metadata.cs index 7ca0acbe92a..3fa988e3288 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Metadata.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Metadata.cs @@ -155,7 +155,7 @@ private static Metadata GetMetadataNoThrow(PortableExecutableReference reference { var filePath = reference.FilePath; - return TryLoadOrCreateAsync( + var result = TryLoadOrCreateAsync( solution, checksum, filePath, @@ -165,6 +165,8 @@ private static Metadata GetMetadataNoThrow(PortableExecutableReference reference getPersistedChecksum: info => info.Checksum, readObject: reader => ReadSymbolTreeInfo(reader, (names, nodes) => GetSpellCheckerTask(solution, checksum, filePath, names, nodes)), cancellationToken: cancellationToken); + Contract.ThrowIfFalse(result != null || loadOnly == true, "Result can only be null if 'loadOnly: true' was passed."); + return result; } private static Task CreateMetadataSymbolTreeInfoAsync( diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Serialization.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Serialization.cs index 5d19ceb9081..cb1a23976f4 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Serialization.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Serialization.cs @@ -19,25 +19,6 @@ internal partial class SymbolTreeInfo : IObjectWritable private const string PrefixMetadataSymbolTreeInfo = ""; private const string SerializationFormat = "17"; - /// - /// Loads the SymbolTreeInfo for a given assembly symbol (metadata or project). If the - /// info can't be loaded, it will be created (and persisted if possible). - /// - private static Task LoadOrCreateSourceSymbolTreeInfoAsync( - Project project, Checksum checksum, bool loadOnly, CancellationToken cancellationToken) - { - return TryLoadOrCreateAsync( - project.Solution, - checksum, - project.FilePath, - loadOnly, - createAsync: () => CreateSourceSymbolTreeInfoAsync(project, checksum, cancellationToken), - keySuffix: "_Source", - getPersistedChecksum: info => info.Checksum, - readObject: reader => ReadSymbolTreeInfo(reader, (names, nodes) => GetSpellCheckerTask(project.Solution, checksum, project.FilePath, names, nodes)), - cancellationToken: cancellationToken); - } - /// /// Loads the SpellChecker for a given assembly symbol (metadata or project). If the /// info can't be loaded, it will be created (and persisted if possible). @@ -48,7 +29,7 @@ internal partial class SymbolTreeInfo : IObjectWritable string filePath, Func> createAsync) { - return TryLoadOrCreateAsync( + var result = TryLoadOrCreateAsync( solution, checksum, filePath, @@ -58,6 +39,8 @@ internal partial class SymbolTreeInfo : IObjectWritable getPersistedChecksum: s => s.Checksum, readObject: SpellChecker.ReadFrom, cancellationToken: CancellationToken.None); + Contract.ThrowIfNull(result, "Result should never be null as we passed 'loadOnly: false'."); + return result; } /// diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Source.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Source.cs index 8c200861b3b..d8ca927426e 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Source.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Source.cs @@ -29,9 +29,17 @@ private static void FreeSymbolMap(MultiDictionary symbolMap) public static Task GetInfoForSourceAssemblyAsync( Project project, Checksum checksum, CancellationToken cancellationToken) { - var result = LoadOrCreateSourceSymbolTreeInfoAsync( - project, checksum, loadOnly: false, cancellationToken: cancellationToken); - Contract.ThrowIfNull(result); + var result = TryLoadOrCreateAsync( + project.Solution, + checksum, + project.FilePath, + loadOnly: false, + createAsync: () => CreateSourceSymbolTreeInfoAsync(project, checksum, cancellationToken), + keySuffix: "_Source", + getPersistedChecksum: info => info.Checksum, + readObject: reader => ReadSymbolTreeInfo(reader, (names, nodes) => GetSpellCheckerTask(project.Solution, checksum, project.FilePath, names, nodes)), + cancellationToken: cancellationToken); + Contract.ThrowIfNull(result, "Result should never be null as we passed 'loadOnly: false'."); return result; } -- GitLab