| File: Compilation\SyntaxAndDeclarationManager.LazyState.cs | Web Access |
| Project: src\roslyn\src\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj (Microsoft.CodeAnalysis.CSharp) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; using Microsoft.CodeAnalysis.Collections; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp { internal sealed partial class SyntaxAndDeclarationManager : CommonSyntaxAndDeclarationManager { internal sealed class State { internal readonly ImmutableArray<SyntaxTree> SyntaxTrees; // In ordinal order. internal readonly ImmutableDictionary<SyntaxTree, int> OrdinalMap; // Inverse of syntaxTrees array (i.e. maps tree to index) internal readonly ImmutableDictionary<SyntaxTree, ImmutableArray<LoadDirective>> LoadDirectiveMap; internal readonly ImmutableDictionary<string, SyntaxTree> LoadedSyntaxTreeMap; internal readonly ImmutableDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> RootNamespaces; /// <summary> /// Mapping from a syntax tree to the last fully computed member names for each the types (in lexical order) /// for this file. Specifically, the key of the collection is the tree the data is cached for. The <see /// cref="OneOrMany"/> is a compact array of items, each of which corresponds to the prior type-declaration /// in the tree that contributed members (in lexical order). Each item in that compact array is then the /// member names for that particular type declaration. /// </summary> /// <remarks> /// Member names often don't change for most edits, so being able to reuse the same set from the last time /// things were computed saves on a lot of memory churn producing the new set, then GC'ing the last set /// (esp. for very large types). The value is stored as a <see cref="OneOrMany"/> as the most common case /// for most files is a single type declaration. /// <para/> /// We store this with weak references so that we can obtain this optimization in the common case where the /// old declaration is still around rooting the old names. If the decls are gone though, the names are subject /// to being cleaned up by the GC and we may not be able to use them. /// </remarks> internal readonly ImmutableDictionary<SyntaxTree, OneOrMany<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>>> LastComputedMemberNames; internal readonly DeclarationTable DeclarationTable; internal State( ImmutableArray<SyntaxTree> syntaxTrees, ImmutableDictionary<SyntaxTree, int> syntaxTreeOrdinalMap, ImmutableDictionary<SyntaxTree, ImmutableArray<LoadDirective>> loadDirectiveMap, ImmutableDictionary<string, SyntaxTree> loadedSyntaxTreeMap, ImmutableDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> rootNamespaces, ImmutableDictionary<SyntaxTree, OneOrMany<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>>> lastComputedMemberNames, DeclarationTable declarationTable) { Debug.Assert(syntaxTrees.All(tree => syntaxTrees[syntaxTreeOrdinalMap[tree]] == tree)); Debug.Assert(syntaxTrees.SetEquals(rootNamespaces.Keys.AsImmutable(), EqualityComparer<SyntaxTree>.Default)); this.SyntaxTrees = syntaxTrees; this.OrdinalMap = syntaxTreeOrdinalMap; this.LoadDirectiveMap = loadDirectiveMap; this.LoadedSyntaxTreeMap = loadedSyntaxTreeMap; this.RootNamespaces = rootNamespaces; this.LastComputedMemberNames = lastComputedMemberNames; this.DeclarationTable = declarationTable; } } } }