455 lines
25 KiB
C#
455 lines
25 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using System.Linq;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
using Microsoft.CodeAnalysis.Collections;
|
|
using Microsoft.CodeAnalysis.PooledObjects;
|
|
using Roslyn.Utilities;
|
|
|
|
namespace Microsoft.CodeAnalysis.CSharp;
|
|
|
|
internal sealed class SyntaxAndDeclarationManager : CommonSyntaxAndDeclarationManager
|
|
{
|
|
internal sealed class State
|
|
{
|
|
internal readonly ImmutableArray<SyntaxTree> SyntaxTrees;
|
|
|
|
internal readonly ImmutableDictionary<SyntaxTree, int> OrdinalMap;
|
|
|
|
internal readonly ImmutableDictionary<SyntaxTree, ImmutableArray<LoadDirective>> LoadDirectiveMap;
|
|
|
|
internal readonly ImmutableDictionary<string, SyntaxTree> LoadedSyntaxTreeMap;
|
|
|
|
internal readonly ImmutableDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> RootNamespaces;
|
|
|
|
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)
|
|
{
|
|
SyntaxTrees = syntaxTrees;
|
|
OrdinalMap = syntaxTreeOrdinalMap;
|
|
LoadDirectiveMap = loadDirectiveMap;
|
|
LoadedSyntaxTreeMap = loadedSyntaxTreeMap;
|
|
RootNamespaces = rootNamespaces;
|
|
LastComputedMemberNames = lastComputedMemberNames;
|
|
DeclarationTable = declarationTable;
|
|
}
|
|
}
|
|
|
|
private static readonly ObjectPool<Stack<SingleNamespaceOrTypeDeclaration>> s_declarationStack = new ObjectPool<Stack<SingleNamespaceOrTypeDeclaration>>((Factory<Stack<SingleNamespaceOrTypeDeclaration>>)(() => new Stack<SingleNamespaceOrTypeDeclaration>()), true);
|
|
|
|
private State _lazyState;
|
|
|
|
internal SyntaxAndDeclarationManager(ImmutableArray<SyntaxTree> externalSyntaxTrees, string scriptClassName, SourceReferenceResolver resolver, CommonMessageProvider messageProvider, bool isSubmission, State state)
|
|
: base(externalSyntaxTrees, scriptClassName, resolver, messageProvider, isSubmission)
|
|
{
|
|
_lazyState = state;
|
|
}
|
|
|
|
internal State GetLazyState()
|
|
{
|
|
if (_lazyState == null)
|
|
{
|
|
Interlocked.CompareExchange(ref _lazyState, CreateState(base.ExternalSyntaxTrees, base.ScriptClassName, base.Resolver, base.MessageProvider, base.IsSubmission), null);
|
|
}
|
|
return _lazyState;
|
|
}
|
|
|
|
private static State CreateState(ImmutableArray<SyntaxTree> externalSyntaxTrees, string scriptClassName, SourceReferenceResolver resolver, CommonMessageProvider messageProvider, bool isSubmission)
|
|
{
|
|
ArrayBuilder<SyntaxTree> instance = ArrayBuilder<SyntaxTree>.GetInstance();
|
|
PooledDictionary<SyntaxTree, int> instance2 = PooledDictionary<SyntaxTree, int>.GetInstance();
|
|
PooledDictionary<SyntaxTree, ImmutableArray<LoadDirective>> instance3 = PooledDictionary<SyntaxTree, ImmutableArray<LoadDirective>>.GetInstance();
|
|
PooledDictionary<string, SyntaxTree> instance4 = PooledDictionary<string, SyntaxTree>.GetInstance();
|
|
PooledDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> instance5 = PooledDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>>.GetInstance();
|
|
PooledDictionary<SyntaxTree, OneOrMany<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>>> instance6 = PooledDictionary<SyntaxTree, OneOrMany<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>>>.GetInstance();
|
|
DeclarationTable declTable = DeclarationTable.Empty;
|
|
ImmutableArray<SyntaxTree>.Enumerator enumerator = externalSyntaxTrees.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
SyntaxTree current = enumerator.Current;
|
|
AppendAllSyntaxTrees(instance, current, scriptClassName, resolver, messageProvider, isSubmission, (IDictionary<SyntaxTree, int>)instance2, (IDictionary<SyntaxTree, ImmutableArray<LoadDirective>>)instance3, (IDictionary<string, SyntaxTree>)instance4, (IDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>>)instance5, (IDictionary<SyntaxTree, OneOrMany<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>>>)instance6, ref declTable);
|
|
}
|
|
return new State(instance.ToImmutableAndFree(), instance2.ToImmutableDictionaryAndFree(), instance3.ToImmutableDictionaryAndFree(), instance4.ToImmutableDictionaryAndFree(), instance5.ToImmutableDictionaryAndFree(), instance6.ToImmutableDictionaryAndFree(), declTable);
|
|
}
|
|
|
|
public SyntaxAndDeclarationManager AddSyntaxTrees(IEnumerable<SyntaxTree> trees)
|
|
{
|
|
string scriptClassName = base.ScriptClassName;
|
|
SourceReferenceResolver resolver = base.Resolver;
|
|
CommonMessageProvider messageProvider = base.MessageProvider;
|
|
bool isSubmission = base.IsSubmission;
|
|
State lazyState = _lazyState;
|
|
ImmutableArray<SyntaxTree> immutableArray = base.ExternalSyntaxTrees.AddRange(trees);
|
|
if (lazyState == null)
|
|
{
|
|
return WithExternalSyntaxTrees(immutableArray);
|
|
}
|
|
ImmutableDictionary<SyntaxTree, int>.Builder builder = lazyState.OrdinalMap.ToBuilder();
|
|
ImmutableDictionary<SyntaxTree, ImmutableArray<LoadDirective>>.Builder builder2 = lazyState.LoadDirectiveMap.ToBuilder();
|
|
ImmutableDictionary<string, SyntaxTree>.Builder builder3 = lazyState.LoadedSyntaxTreeMap.ToBuilder();
|
|
ImmutableDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>>.Builder builder4 = lazyState.RootNamespaces.ToBuilder();
|
|
ImmutableDictionary<SyntaxTree, OneOrMany<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>>>.Builder builder5 = lazyState.LastComputedMemberNames.ToBuilder();
|
|
DeclarationTable declTable = lazyState.DeclarationTable;
|
|
ArrayBuilder<SyntaxTree> instance = ArrayBuilder<SyntaxTree>.GetInstance();
|
|
instance.AddRange(lazyState.SyntaxTrees);
|
|
foreach (SyntaxTree tree in trees)
|
|
{
|
|
AppendAllSyntaxTrees(instance, tree, scriptClassName, resolver, messageProvider, isSubmission, builder, builder2, builder3, builder4, builder5, ref declTable);
|
|
}
|
|
lazyState = new State(instance.ToImmutableAndFree(), builder.ToImmutableDictionary(), builder2.ToImmutableDictionary(), builder3.ToImmutableDictionary(), builder4.ToImmutableDictionary(), builder5.ToImmutableDictionary(), declTable);
|
|
return new SyntaxAndDeclarationManager(immutableArray, scriptClassName, resolver, messageProvider, isSubmission, lazyState);
|
|
}
|
|
|
|
private static void AppendAllSyntaxTrees(ArrayBuilder<SyntaxTree> treesBuilder, SyntaxTree tree, string scriptClassName, SourceReferenceResolver resolver, CommonMessageProvider messageProvider, bool isSubmission, IDictionary<SyntaxTree, int> ordinalMapBuilder, IDictionary<SyntaxTree, ImmutableArray<LoadDirective>> loadDirectiveMapBuilder, IDictionary<string, SyntaxTree> loadedSyntaxTreeMapBuilder, IDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> declMapBuilder, IDictionary<SyntaxTree, OneOrMany<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>>> lastComputedMemberNamesMap, ref DeclarationTable declTable)
|
|
{
|
|
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_000c: Invalid comparison between Unknown and I4
|
|
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
|
|
if ((int)tree.Options.Kind == 1)
|
|
{
|
|
AppendAllLoadedSyntaxTrees(treesBuilder, tree, scriptClassName, resolver, messageProvider, isSubmission, ordinalMapBuilder, loadDirectiveMapBuilder, loadedSyntaxTreeMapBuilder, declMapBuilder, lastComputedMemberNamesMap, ref declTable);
|
|
}
|
|
AddSyntaxTreeToDeclarationMapAndTable(tree, scriptClassName, isSubmission, declMapBuilder, OneOrMany<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>>.Empty, ref declTable);
|
|
treesBuilder.Add(tree);
|
|
ordinalMapBuilder.Add(tree, ordinalMapBuilder.Count);
|
|
lastComputedMemberNamesMap.Add(tree, OneOrMany<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>>.Empty);
|
|
}
|
|
|
|
private static void AppendAllLoadedSyntaxTrees(ArrayBuilder<SyntaxTree> treesBuilder, SyntaxTree tree, string scriptClassName, SourceReferenceResolver resolver, CommonMessageProvider messageProvider, bool isSubmission, IDictionary<SyntaxTree, int> ordinalMapBuilder, IDictionary<SyntaxTree, ImmutableArray<LoadDirective>> loadDirectiveMapBuilder, IDictionary<string, SyntaxTree> loadedSyntaxTreeMapBuilder, IDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> declMapBuilder, IDictionary<SyntaxTree, OneOrMany<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>>> lastComputedMemberNamesMap, ref DeclarationTable declTable)
|
|
{
|
|
//IL_013a: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
|
|
ArrayBuilder<LoadDirective> val = null;
|
|
foreach (LoadDirectiveTriviaSyntax loadDirective in tree.GetCompilationUnitRoot().GetLoadDirectives())
|
|
{
|
|
SyntaxToken file = loadDirective.File;
|
|
string text = (string)((SyntaxToken)(ref file)).Value;
|
|
if (text == null)
|
|
{
|
|
continue;
|
|
}
|
|
DiagnosticBag instance = DiagnosticBag.GetInstance();
|
|
string text2 = null;
|
|
if (resolver == null)
|
|
{
|
|
instance.Add(messageProvider.CreateDiagnostic(8099, ((SyntaxNode)loadDirective).Location));
|
|
}
|
|
else
|
|
{
|
|
text2 = resolver.ResolveReference(text, tree.FilePath);
|
|
if (text2 == null)
|
|
{
|
|
instance.Add(messageProvider.CreateDiagnostic(1504, ((SyntaxToken)(ref file)).GetLocation(), new object[2]
|
|
{
|
|
text,
|
|
CSharpResources.CouldNotFindFile
|
|
}));
|
|
}
|
|
else if (!loadedSyntaxTreeMapBuilder.ContainsKey(text2))
|
|
{
|
|
try
|
|
{
|
|
SyntaxTree val2 = SyntaxFactory.ParseSyntaxTree(resolver.ReadText(text2), tree.Options, text2);
|
|
loadedSyntaxTreeMapBuilder.Add(val2.FilePath, val2);
|
|
AppendAllSyntaxTrees(treesBuilder, val2, scriptClassName, resolver, messageProvider, isSubmission, ordinalMapBuilder, loadDirectiveMapBuilder, loadedSyntaxTreeMapBuilder, declMapBuilder, lastComputedMemberNamesMap, ref declTable);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
instance.Add(CommonCompiler.ToFileReadDiagnostics(messageProvider, ex, text2), ((SyntaxToken)(ref file)).GetLocation());
|
|
}
|
|
}
|
|
}
|
|
if (val == null)
|
|
{
|
|
val = ArrayBuilder<LoadDirective>.GetInstance();
|
|
}
|
|
val.Add(new LoadDirective(text2, instance.ToReadOnlyAndFree()));
|
|
}
|
|
if (val != null)
|
|
{
|
|
loadDirectiveMapBuilder.Add(tree, val.ToImmutableAndFree());
|
|
}
|
|
}
|
|
|
|
private static void AddSyntaxTreeToDeclarationMapAndTable(SyntaxTree tree, string scriptClassName, bool isSubmission, IDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> declMapBuilder, OneOrMany<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>> lastComputedMemberNames, ref DeclarationTable declTable)
|
|
{
|
|
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
|
|
Lazy<RootSingleNamespaceDeclaration> lazy = new Lazy<RootSingleNamespaceDeclaration>(() => DeclarationTreeBuilder.ForTree(tree, scriptClassName, isSubmission, lastComputedMemberNames));
|
|
declMapBuilder.Add(tree, lazy);
|
|
declTable = declTable.AddRootDeclaration(lazy);
|
|
}
|
|
|
|
public SyntaxAndDeclarationManager RemoveSyntaxTrees(HashSet<SyntaxTree> trees)
|
|
{
|
|
State lazyState = _lazyState;
|
|
ImmutableArray<SyntaxTree> immutableArray = base.ExternalSyntaxTrees.RemoveAll((SyntaxTree t) => trees.Contains(t));
|
|
if (lazyState == null)
|
|
{
|
|
return WithExternalSyntaxTrees(immutableArray);
|
|
}
|
|
ImmutableArray<SyntaxTree> syntaxTrees = lazyState.SyntaxTrees;
|
|
ImmutableDictionary<SyntaxTree, ImmutableArray<LoadDirective>> immutableDictionary = lazyState.LoadDirectiveMap;
|
|
ImmutableDictionary<string, SyntaxTree> immutableDictionary2 = lazyState.LoadedSyntaxTreeMap;
|
|
PooledHashSet<SyntaxTree> instance = PooledHashSet<SyntaxTree>.GetInstance();
|
|
foreach (SyntaxTree tree in trees)
|
|
{
|
|
GetRemoveSet(tree, includeLoadedTrees: true, syntaxTrees, lazyState.OrdinalMap, immutableDictionary, immutableDictionary2, (HashSet<SyntaxTree>)(object)instance, out var _, out var _);
|
|
}
|
|
ArrayBuilder<SyntaxTree> instance2 = ArrayBuilder<SyntaxTree>.GetInstance();
|
|
PooledDictionary<SyntaxTree, int> instance3 = PooledDictionary<SyntaxTree, int>.GetInstance();
|
|
ImmutableDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>>.Builder builder = lazyState.RootNamespaces.ToBuilder();
|
|
ImmutableDictionary<SyntaxTree, OneOrMany<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>>>.Builder builder2 = lazyState.LastComputedMemberNames.ToBuilder();
|
|
DeclarationTable declTable = lazyState.DeclarationTable;
|
|
ImmutableArray<SyntaxTree>.Enumerator enumerator2 = syntaxTrees.GetEnumerator();
|
|
while (enumerator2.MoveNext())
|
|
{
|
|
SyntaxTree current = enumerator2.Current;
|
|
if (((HashSet<SyntaxTree>)(object)instance).Contains(current))
|
|
{
|
|
immutableDictionary = immutableDictionary.Remove(current);
|
|
immutableDictionary2 = immutableDictionary2.Remove(current.FilePath);
|
|
builder2.Remove(current);
|
|
RemoveSyntaxTreeFromDeclarationMapAndTable(current, builder, ref declTable);
|
|
}
|
|
else if (!IsLoadedSyntaxTree(current, immutableDictionary2))
|
|
{
|
|
UpdateSyntaxTreesAndOrdinalMapOnly(instance2, current, (IDictionary<SyntaxTree, int>)instance3, immutableDictionary, immutableDictionary2);
|
|
}
|
|
}
|
|
instance.Free();
|
|
lazyState = new State(instance2.ToImmutableAndFree(), instance3.ToImmutableDictionaryAndFree(), immutableDictionary, immutableDictionary2, builder.ToImmutableDictionary(), builder2.ToImmutableDictionary(), declTable);
|
|
return new SyntaxAndDeclarationManager(immutableArray, base.ScriptClassName, base.Resolver, base.MessageProvider, base.IsSubmission, lazyState);
|
|
}
|
|
|
|
private static void GetRemoveSet(SyntaxTree oldTree, bool includeLoadedTrees, ImmutableArray<SyntaxTree> syntaxTrees, ImmutableDictionary<SyntaxTree, int> syntaxTreeOrdinalMap, ImmutableDictionary<SyntaxTree, ImmutableArray<LoadDirective>> loadDirectiveMap, ImmutableDictionary<string, SyntaxTree> loadedSyntaxTreeMap, HashSet<SyntaxTree> removeSet, out int totalReferencedTreeCount, out ImmutableArray<LoadDirective> oldLoadDirectives)
|
|
{
|
|
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
|
|
if (includeLoadedTrees && loadDirectiveMap.TryGetValue(oldTree, out oldLoadDirectives))
|
|
{
|
|
GetRemoveSetForLoadedTrees(oldLoadDirectives, loadDirectiveMap, loadedSyntaxTreeMap, removeSet);
|
|
}
|
|
else
|
|
{
|
|
oldLoadDirectives = ImmutableArray<LoadDirective>.Empty;
|
|
}
|
|
removeSet.Add(oldTree);
|
|
totalReferencedTreeCount = removeSet.Count;
|
|
if (removeSet.Count <= 1)
|
|
{
|
|
return;
|
|
}
|
|
for (int i = syntaxTreeOrdinalMap[oldTree] + 1; i < syntaxTrees.Length; i++)
|
|
{
|
|
SyntaxTree key = syntaxTrees[i];
|
|
if (!loadDirectiveMap.TryGetValue(key, out var value))
|
|
{
|
|
continue;
|
|
}
|
|
ImmutableArray<LoadDirective>.Enumerator enumerator = value.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
LoadDirective current = enumerator.Current;
|
|
if (TryGetLoadedSyntaxTree(loadedSyntaxTreeMap, current, out var loadedTree))
|
|
{
|
|
removeSet.Remove(loadedTree);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void GetRemoveSetForLoadedTrees(ImmutableArray<LoadDirective> loadDirectives, ImmutableDictionary<SyntaxTree, ImmutableArray<LoadDirective>> loadDirectiveMap, ImmutableDictionary<string, SyntaxTree> loadedSyntaxTreeMap, HashSet<SyntaxTree> removeSet)
|
|
{
|
|
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
|
|
ImmutableArray<LoadDirective>.Enumerator enumerator = loadDirectives.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
LoadDirective current = enumerator.Current;
|
|
if (current.ResolvedPath != null && TryGetLoadedSyntaxTree(loadedSyntaxTreeMap, current, out var loadedTree) && removeSet.Add(loadedTree) && loadDirectiveMap.TryGetValue(loadedTree, out var value))
|
|
{
|
|
GetRemoveSetForLoadedTrees(value, loadDirectiveMap, loadedSyntaxTreeMap, removeSet);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void RemoveSyntaxTreeFromDeclarationMapAndTable(SyntaxTree tree, IDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> declMap, ref DeclarationTable declTable)
|
|
{
|
|
Lazy<RootSingleNamespaceDeclaration> lazyRootDeclaration = declMap[tree];
|
|
declTable = declTable.RemoveRootDeclaration(lazyRootDeclaration);
|
|
declMap.Remove(tree);
|
|
}
|
|
|
|
public SyntaxAndDeclarationManager ReplaceSyntaxTree(SyntaxTree oldTree, SyntaxTree newTree)
|
|
{
|
|
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0211: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0251: Unknown result type (might be due to invalid IL or missing references)
|
|
State lazyState = _lazyState;
|
|
ImmutableArray<SyntaxTree> immutableArray = base.ExternalSyntaxTrees.Replace(oldTree, newTree);
|
|
if (lazyState == null)
|
|
{
|
|
return WithExternalSyntaxTrees(immutableArray);
|
|
}
|
|
IList<LoadDirectiveTriviaSyntax> loadDirectives = newTree.GetCompilationUnitRoot().GetLoadDirectives();
|
|
bool flag = !oldTree.GetCompilationUnitRoot().GetLoadDirectives().SequenceEqual(loadDirectives);
|
|
ImmutableArray<SyntaxTree> syntaxTrees = lazyState.SyntaxTrees;
|
|
ImmutableDictionary<SyntaxTree, int> ordinalMap = lazyState.OrdinalMap;
|
|
ImmutableDictionary<SyntaxTree, ImmutableArray<LoadDirective>> loadDirectiveMap = lazyState.LoadDirectiveMap;
|
|
ImmutableDictionary<string, SyntaxTree> loadedSyntaxTreeMap = lazyState.LoadedSyntaxTreeMap;
|
|
PooledHashSet<SyntaxTree> instance = PooledHashSet<SyntaxTree>.GetInstance();
|
|
GetRemoveSet(oldTree, flag, syntaxTrees, ordinalMap, loadDirectiveMap, loadedSyntaxTreeMap, (HashSet<SyntaxTree>)(object)instance, out var totalReferencedTreeCount, out var oldLoadDirectives);
|
|
ImmutableDictionary<SyntaxTree, ImmutableArray<LoadDirective>>.Builder builder = loadDirectiveMap.ToBuilder();
|
|
ImmutableDictionary<string, SyntaxTree>.Builder builder2 = loadedSyntaxTreeMap.ToBuilder();
|
|
ImmutableDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>>.Builder builder3 = lazyState.RootNamespaces.ToBuilder();
|
|
ImmutableDictionary<SyntaxTree, OneOrMany<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>>>.Builder builder4 = lazyState.LastComputedMemberNames.ToBuilder();
|
|
DeclarationTable declTable = lazyState.DeclarationTable;
|
|
OneOrMany<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>> val = tryGetLastComputedMemberNames(oldTree, builder3, builder4);
|
|
foreach (SyntaxTree item in (HashSet<SyntaxTree>)(object)instance)
|
|
{
|
|
builder.Remove(item);
|
|
builder2.Remove(item.FilePath);
|
|
builder4.Remove(item);
|
|
RemoveSyntaxTreeFromDeclarationMapAndTable(item, builder3, ref declTable);
|
|
}
|
|
instance.Free();
|
|
int num = ordinalMap[oldTree];
|
|
ImmutableArray<SyntaxTree> syntaxTrees2;
|
|
if (flag)
|
|
{
|
|
ArrayBuilder<SyntaxTree> instance2 = ArrayBuilder<SyntaxTree>.GetInstance();
|
|
PooledDictionary<SyntaxTree, int> instance3 = PooledDictionary<SyntaxTree, int>.GetInstance();
|
|
for (int i = 0; i <= num - totalReferencedTreeCount; i++)
|
|
{
|
|
SyntaxTree val2 = syntaxTrees[i];
|
|
instance2.Add(val2);
|
|
((Dictionary<SyntaxTree, int>)(object)instance3).Add(val2, i);
|
|
}
|
|
AppendAllSyntaxTrees(instance2, newTree, base.ScriptClassName, base.Resolver, base.MessageProvider, base.IsSubmission, (IDictionary<SyntaxTree, int>)instance3, builder, builder2, builder3, builder4, ref declTable);
|
|
for (int j = num + 1; j < syntaxTrees.Length; j++)
|
|
{
|
|
SyntaxTree tree = syntaxTrees[j];
|
|
if (!IsLoadedSyntaxTree(tree, loadedSyntaxTreeMap))
|
|
{
|
|
UpdateSyntaxTreesAndOrdinalMapOnly(instance2, tree, (IDictionary<SyntaxTree, int>)instance3, loadDirectiveMap, loadedSyntaxTreeMap);
|
|
}
|
|
}
|
|
syntaxTrees2 = instance2.ToImmutableAndFree();
|
|
ordinalMap = instance3.ToImmutableDictionaryAndFree();
|
|
}
|
|
else
|
|
{
|
|
AddSyntaxTreeToDeclarationMapAndTable(newTree, base.ScriptClassName, base.IsSubmission, builder3, val, ref declTable);
|
|
if (loadDirectives.Any())
|
|
{
|
|
builder[newTree] = oldLoadDirectives;
|
|
}
|
|
syntaxTrees2 = syntaxTrees.SetItem(num, newTree);
|
|
ordinalMap = ordinalMap.Remove(oldTree);
|
|
ordinalMap = ordinalMap.SetItem(newTree, num);
|
|
builder4.Add(newTree, val);
|
|
}
|
|
lazyState = new State(syntaxTrees2, ordinalMap, builder.ToImmutable(), builder2.ToImmutable(), builder3.ToImmutable(), builder4.ToImmutable(), declTable);
|
|
return new SyntaxAndDeclarationManager(immutableArray, base.ScriptClassName, base.Resolver, base.MessageProvider, base.IsSubmission, lazyState);
|
|
static OneOrMany<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>> tryGetLastComputedMemberNames(SyntaxTree key, ImmutableDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>>.Builder declMapBuilder, ImmutableDictionary<SyntaxTree, OneOrMany<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>>>.Builder lastComputedMemberNamesMap)
|
|
{
|
|
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
|
|
Lazy<RootSingleNamespaceDeclaration> lazy = declMapBuilder[key];
|
|
if (lazy.IsValueCreated)
|
|
{
|
|
Stack<SingleNamespaceOrTypeDeclaration> stack = s_declarationStack.Allocate();
|
|
stack.Push(lazy.Value);
|
|
ArrayBuilder<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>> instance4 = ArrayBuilder<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>>.GetInstance();
|
|
do
|
|
{
|
|
SingleNamespaceOrTypeDeclaration singleNamespaceOrTypeDeclaration = stack.Pop();
|
|
for (int num2 = singleNamespaceOrTypeDeclaration.Children.Length - 1; num2 >= 0; num2--)
|
|
{
|
|
stack.Push(singleNamespaceOrTypeDeclaration.Children[num2]);
|
|
}
|
|
if (singleNamespaceOrTypeDeclaration is SingleTypeDeclaration singleTypeDeclaration && DeclarationTreeBuilder.CachesComputedMemberNames(singleTypeDeclaration))
|
|
{
|
|
instance4.Add(new WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>(singleTypeDeclaration.MemberNames));
|
|
}
|
|
}
|
|
while (stack.Count > 0);
|
|
s_declarationStack.Free(stack);
|
|
return ArrayBuilderExtensions.ToOneOrManyAndFree<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>>(instance4);
|
|
}
|
|
if (lastComputedMemberNamesMap.TryGetValue(key, out var value))
|
|
{
|
|
return value;
|
|
}
|
|
return OneOrMany<WeakReference<StrongBox<ImmutableSegmentedHashSet<string>>>>.Empty;
|
|
}
|
|
}
|
|
|
|
internal SyntaxAndDeclarationManager WithExternalSyntaxTrees(ImmutableArray<SyntaxTree> trees)
|
|
{
|
|
return new SyntaxAndDeclarationManager(trees, base.ScriptClassName, base.Resolver, base.MessageProvider, base.IsSubmission, null);
|
|
}
|
|
|
|
internal static bool IsLoadedSyntaxTree(SyntaxTree tree, ImmutableDictionary<string, SyntaxTree> loadedSyntaxTreeMap)
|
|
{
|
|
if (loadedSyntaxTreeMap.TryGetValue(tree.FilePath, out var value))
|
|
{
|
|
return tree == value;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private static void UpdateSyntaxTreesAndOrdinalMapOnly(ArrayBuilder<SyntaxTree> treesBuilder, SyntaxTree tree, IDictionary<SyntaxTree, int> ordinalMapBuilder, ImmutableDictionary<SyntaxTree, ImmutableArray<LoadDirective>> loadDirectiveMap, ImmutableDictionary<string, SyntaxTree> loadedSyntaxTreeMap)
|
|
{
|
|
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_000c: Invalid comparison between Unknown and I4
|
|
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
|
|
if ((int)tree.Options.Kind == 1 && loadDirectiveMap.TryGetValue(tree, out var value))
|
|
{
|
|
ImmutableArray<LoadDirective>.Enumerator enumerator = value.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
LoadDirective current = enumerator.Current;
|
|
if (current.ResolvedPath != null && TryGetLoadedSyntaxTree(loadedSyntaxTreeMap, current, out var loadedTree))
|
|
{
|
|
UpdateSyntaxTreesAndOrdinalMapOnly(treesBuilder, loadedTree, ordinalMapBuilder, loadDirectiveMap, loadedSyntaxTreeMap);
|
|
}
|
|
}
|
|
}
|
|
treesBuilder.Add(tree);
|
|
ordinalMapBuilder.Add(tree, ordinalMapBuilder.Count);
|
|
}
|
|
|
|
internal bool MayHaveReferenceDirectives()
|
|
{
|
|
return _lazyState?.DeclarationTable.ReferenceDirectives.Any() ?? base.ExternalSyntaxTrees.Any((SyntaxTree t) => t.HasReferenceOrLoadDirectives());
|
|
}
|
|
|
|
private static bool TryGetLoadedSyntaxTree(ImmutableDictionary<string, SyntaxTree> loadedSyntaxTreeMap, LoadDirective directive, out SyntaxTree loadedTree)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
if (loadedSyntaxTreeMap.TryGetValue(directive.ResolvedPath, out loadedTree))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|