提交 f7a19b70 编写于 作者: C Cyrus Najmabadi

Use simple using statement

上级 2732b85f
......@@ -16,27 +16,26 @@ public static AssemblyIdentity TryGetAssemblyIdentity(string filePath)
{
try
{
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
using (var peReader = new PEReader(stream))
{
var metadataReader = peReader.GetMetadataReader();
AssemblyDefinition assemblyDefinition = metadataReader.GetAssemblyDefinition();
string name = metadataReader.GetString(assemblyDefinition.Name);
Version version = assemblyDefinition.Version;
StringHandle cultureHandle = assemblyDefinition.Culture;
string cultureName = (!cultureHandle.IsNil) ? metadataReader.GetString(cultureHandle) : null;
AssemblyFlags flags = assemblyDefinition.Flags;
bool hasPublicKey = (flags & AssemblyFlags.PublicKey) != 0;
BlobHandle publicKeyHandle = assemblyDefinition.PublicKey;
ImmutableArray<byte> publicKeyOrToken = !publicKeyHandle.IsNil
? metadataReader.GetBlobBytes(publicKeyHandle).AsImmutableOrNull()
: default;
return new AssemblyIdentity(name, version, cultureName, publicKeyOrToken, hasPublicKey);
}
using var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
using var peReader = new PEReader(stream);
var metadataReader = peReader.GetMetadataReader();
AssemblyDefinition assemblyDefinition = metadataReader.GetAssemblyDefinition();
string name = metadataReader.GetString(assemblyDefinition.Name);
Version version = assemblyDefinition.Version;
StringHandle cultureHandle = assemblyDefinition.Culture;
string cultureName = (!cultureHandle.IsNil) ? metadataReader.GetString(cultureHandle) : null;
AssemblyFlags flags = assemblyDefinition.Flags;
bool hasPublicKey = (flags & AssemblyFlags.PublicKey) != 0;
BlobHandle publicKeyHandle = assemblyDefinition.PublicKey;
ImmutableArray<byte> publicKeyOrToken = !publicKeyHandle.IsNil
? metadataReader.GetBlobBytes(publicKeyHandle).AsImmutableOrNull()
: default;
return new AssemblyIdentity(name, version, cultureName, publicKeyOrToken, hasPublicKey);
}
catch { }
......
......@@ -38,20 +38,18 @@ public DiagnosticDataSerializer(VersionStamp analyzerVersion, VersionStamp versi
public async Task<bool> SerializeAsync(object documentOrProject, string key, ImmutableArray<DiagnosticData> items, CancellationToken cancellationToken)
{
using (var stream = SerializableBytes.CreateWritableStream())
using (var writer = new ObjectWriter(stream, cancellationToken: cancellationToken))
{
WriteTo(writer, items, cancellationToken);
using var stream = SerializableBytes.CreateWritableStream();
using var writer = new ObjectWriter(stream, cancellationToken: cancellationToken);
var solution = GetSolution(documentOrProject);
var persistService = solution.Workspace.Services.GetService<IPersistentStorageService>();
WriteTo(writer, items, cancellationToken);
using (var storage = persistService.GetStorage(solution))
{
stream.Position = 0;
return await WriteStreamAsync(storage, documentOrProject, key, stream, cancellationToken).ConfigureAwait(false);
}
}
var solution = GetSolution(documentOrProject);
var persistService = solution.Workspace.Services.GetService<IPersistentStorageService>();
using var storage = persistService.GetStorage(solution);
stream.Position = 0;
return await WriteStreamAsync(storage, documentOrProject, key, stream, cancellationToken).ConfigureAwait(false);
}
public async Task<StrongBox<ImmutableArray<DiagnosticData>>> DeserializeAsync(object documentOrProject, string key, CancellationToken cancellationToken)
......@@ -60,19 +58,18 @@ public async Task<StrongBox<ImmutableArray<DiagnosticData>>> DeserializeAsync(ob
var solution = GetSolution(documentOrProject);
var persistService = solution.Workspace.Services.GetService<IPersistentStorageService>();
using (var storage = persistService.GetStorage(solution))
using (var stream = await ReadStreamAsync(storage, key, documentOrProject, cancellationToken).ConfigureAwait(false))
using (var reader = ObjectReader.TryGetReader(stream))
{
if (reader == null)
{
return null;
}
using var storage = persistService.GetStorage(solution);
using var stream = await ReadStreamAsync(storage, key, documentOrProject, cancellationToken).ConfigureAwait(false);
using var reader = ObjectReader.TryGetReader(stream);
// we return StrongBox rather than ImmutableArray due to task lib's issue with allocations
// when returning default(value type)
return ReadFrom(reader, documentOrProject, cancellationToken);
if (reader == null)
{
return null;
}
// we return StrongBox rather than ImmutableArray due to task lib's issue with allocations
// when returning default(value type)
return ReadFrom(reader, documentOrProject, cancellationToken);
}
private Task<bool> WriteStreamAsync(IPersistentStorage storage, object documentOrProject, string key, Stream stream, CancellationToken cancellationToken)
......@@ -219,33 +216,32 @@ private StrongBox<ImmutableArray<DiagnosticData>> ReadFrom(ObjectReader reader,
{
try
{
using (var pooledObject = SharedPools.Default<List<DiagnosticData>>().GetPooledObject())
using var pooledObject = SharedPools.Default<List<DiagnosticData>>().GetPooledObject();
var list = pooledObject.Object;
var format = reader.ReadInt32();
if (format != FormatVersion)
{
return null;
}
// saved data is for same analyzer of different version of dll
var analyzerVersion = VersionStamp.ReadFrom(reader);
if (analyzerVersion != AnalyzerVersion)
{
var list = pooledObject.Object;
var format = reader.ReadInt32();
if (format != FormatVersion)
{
return null;
}
// saved data is for same analyzer of different version of dll
var analyzerVersion = VersionStamp.ReadFrom(reader);
if (analyzerVersion != AnalyzerVersion)
{
return null;
}
var version = VersionStamp.ReadFrom(reader);
if (version != VersionStamp.Default && version != Version)
{
return null;
}
ReadFrom(reader, project, document, list, cancellationToken);
return new StrongBox<ImmutableArray<DiagnosticData>>(list.ToImmutableArray());
return null;
}
var version = VersionStamp.ReadFrom(reader);
if (version != VersionStamp.Default && version != Version)
{
return null;
}
ReadFrom(reader, project, document, list, cancellationToken);
return new StrongBox<ImmutableArray<DiagnosticData>>(list.ToImmutableArray());
}
catch (Exception)
{
......
......@@ -89,35 +89,34 @@ public Checksum CreateChecksum(AnalyzerReference reference, bool usePathFromAsse
{
cancellationToken.ThrowIfCancellationRequested();
using (var stream = SerializableBytes.CreateWritableStream())
using (var writer = new ObjectWriter(stream, cancellationToken: cancellationToken))
{
switch (reference)
{
case AnalyzerFileReference file:
WriteAnalyzerFileReferenceMvid(file, writer, usePathFromAssembly, cancellationToken);
break;
using var stream = SerializableBytes.CreateWritableStream();
using var writer = new ObjectWriter(stream, cancellationToken: cancellationToken);
case UnresolvedAnalyzerReference unresolved:
WriteUnresolvedAnalyzerReferenceTo(unresolved, writer);
break;
switch (reference)
{
case AnalyzerFileReference file:
WriteAnalyzerFileReferenceMvid(file, writer, usePathFromAssembly, cancellationToken);
break;
case AnalyzerReference analyzerReference when analyzerReference.GetType().FullName == VisualStudioUnresolvedAnalyzerReference:
WriteUnresolvedAnalyzerReferenceTo(analyzerReference, writer);
break;
case UnresolvedAnalyzerReference unresolved:
WriteUnresolvedAnalyzerReferenceTo(unresolved, writer);
break;
case AnalyzerImageReference _:
// TODO: think a way to support this or a way to deal with this kind of situation.
// https://github.com/dotnet/roslyn/issues/15783
throw new NotSupportedException(nameof(AnalyzerImageReference));
case AnalyzerReference analyzerReference when analyzerReference.GetType().FullName == VisualStudioUnresolvedAnalyzerReference:
WriteUnresolvedAnalyzerReferenceTo(analyzerReference, writer);
break;
default:
throw ExceptionUtilities.UnexpectedValue(reference);
}
case AnalyzerImageReference _:
// TODO: think a way to support this or a way to deal with this kind of situation.
// https://github.com/dotnet/roslyn/issues/15783
throw new NotSupportedException(nameof(AnalyzerImageReference));
stream.Position = 0;
return Checksum.Create(stream);
default:
throw ExceptionUtilities.UnexpectedValue(reference);
}
stream.Position = 0;
return Checksum.Create(stream);
}
public void WriteTo(MetadataReference reference, ObjectWriter writer, CancellationToken cancellationToken)
......@@ -246,16 +245,15 @@ public AnalyzerReference ReadAnalyzerReferenceFrom(ObjectReader reader, Cancella
// picked up the dll
var assemblyPath = usePathFromAssembly ? TryGetAnalyzerAssemblyPath(file) : file.FullPath;
using (var stream = new FileStream(assemblyPath, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete))
using (var peReader = new PEReader(stream))
{
var metadataReader = peReader.GetMetadataReader();
using var stream = new FileStream(assemblyPath, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete);
using var peReader = new PEReader(stream);
var mvidHandle = metadataReader.GetModuleDefinition().Mvid;
var guid = metadataReader.GetGuid(mvidHandle);
var metadataReader = peReader.GetMetadataReader();
writer.WriteGuid(guid);
}
var mvidHandle = metadataReader.GetModuleDefinition().Mvid;
var guid = metadataReader.GetGuid(mvidHandle);
writer.WriteGuid(guid);
}
catch
{
......@@ -282,15 +280,14 @@ private void WritePortableExecutableReferencePropertiesTo(PortableExecutableRefe
private Checksum CreatePortableExecutableReferenceChecksum(PortableExecutableReference reference, CancellationToken cancellationToken)
{
using (var stream = SerializableBytes.CreateWritableStream())
using (var writer = new ObjectWriter(stream, cancellationToken: cancellationToken))
{
WritePortableExecutableReferencePropertiesTo(reference, writer, cancellationToken);
WriteMvidsTo(TryGetMetadata(reference), writer, cancellationToken);
using var stream = SerializableBytes.CreateWritableStream();
using var writer = new ObjectWriter(stream, cancellationToken: cancellationToken);
stream.Position = 0;
return Checksum.Create(stream);
}
WritePortableExecutableReferencePropertiesTo(reference, writer, cancellationToken);
WriteMvidsTo(TryGetMetadata(reference), writer, cancellationToken);
stream.Position = 0;
return Checksum.Create(stream);
}
private void WriteMvidsTo(Metadata metadata, ObjectWriter writer, CancellationToken cancellationToken)
......@@ -469,34 +466,33 @@ private void WriteTo(Metadata metadata, ObjectWriter writer, CancellationToken c
return false;
}
using (var pooled = Creator.CreateList<(string name, long offset, long size)>())
using var pooled = Creator.CreateList<(string name, long offset, long size)>();
foreach (var storage in storages)
{
foreach (var storage in storages)
var storage2 = storage as ITemporaryStorageWithName;
if (storage2 == null)
{
var storage2 = storage as ITemporaryStorageWithName;
if (storage2 == null)
{
return false;
}
pooled.Object.Add((storage2.Name, storage2.Offset, storage2.Size));
return false;
}
WritePortableExecutableReferenceHeaderTo((PortableExecutableReference)reference, SerializationKinds.MemoryMapFile, writer, cancellationToken);
pooled.Object.Add((storage2.Name, storage2.Offset, storage2.Size));
}
writer.WriteInt32((int)MetadataImageKind.Assembly);
writer.WriteInt32(pooled.Object.Count);
WritePortableExecutableReferenceHeaderTo((PortableExecutableReference)reference, SerializationKinds.MemoryMapFile, writer, cancellationToken);
foreach (var tuple in pooled.Object)
{
writer.WriteInt32((int)MetadataImageKind.Module);
writer.WriteString(tuple.name);
writer.WriteInt64(tuple.offset);
writer.WriteInt64(tuple.size);
}
writer.WriteInt32((int)MetadataImageKind.Assembly);
writer.WriteInt32(pooled.Object.Count);
return true;
foreach (var tuple in pooled.Object)
{
writer.WriteInt32((int)MetadataImageKind.Module);
writer.WriteString(tuple.name);
writer.WriteInt64(tuple.offset);
writer.WriteInt64(tuple.size);
}
return true;
}
private (Metadata metadata, ImmutableArray<ITemporaryStreamStorage> storages)? TryReadMetadataFrom(
......@@ -514,19 +510,18 @@ private void WriteTo(Metadata metadata, ObjectWriter writer, CancellationToken c
{
if (metadataKind == MetadataImageKind.Assembly)
{
using (var pooledMetadata = Creator.CreateList<ModuleMetadata>())
{
var count = reader.ReadInt32();
for (var i = 0; i < count; i++)
{
metadataKind = (MetadataImageKind)reader.ReadInt32();
Contract.ThrowIfFalse(metadataKind == MetadataImageKind.Module);
using var pooledMetadata = Creator.CreateList<ModuleMetadata>();
pooledMetadata.Object.Add(ReadModuleMetadataFrom(reader, kind));
}
var count = reader.ReadInt32();
for (var i = 0; i < count; i++)
{
metadataKind = (MetadataImageKind)reader.ReadInt32();
Contract.ThrowIfFalse(metadataKind == MetadataImageKind.Module);
return (AssemblyMetadata.Create(pooledMetadata.Object), storages: default);
pooledMetadata.Object.Add(ReadModuleMetadataFrom(reader, kind));
}
return (AssemblyMetadata.Create(pooledMetadata.Object), storages: default);
}
Contract.ThrowIfFalse(metadataKind == MetadataImageKind.Module);
......@@ -535,23 +530,22 @@ private void WriteTo(Metadata metadata, ObjectWriter writer, CancellationToken c
if (metadataKind == MetadataImageKind.Assembly)
{
using (var pooledMetadata = Creator.CreateList<ModuleMetadata>())
using (var pooledStorage = Creator.CreateList<ITemporaryStreamStorage>())
{
var count = reader.ReadInt32();
for (var i = 0; i < count; i++)
{
metadataKind = (MetadataImageKind)reader.ReadInt32();
Contract.ThrowIfFalse(metadataKind == MetadataImageKind.Module);
using var pooledMetadata = Creator.CreateList<ModuleMetadata>();
using var pooledStorage = Creator.CreateList<ITemporaryStreamStorage>();
var (metadata, storage) = ReadModuleMetadataFrom(reader, kind, cancellationToken);
var count = reader.ReadInt32();
for (var i = 0; i < count; i++)
{
metadataKind = (MetadataImageKind)reader.ReadInt32();
Contract.ThrowIfFalse(metadataKind == MetadataImageKind.Module);
pooledMetadata.Object.Add(metadata);
pooledStorage.Object.Add(storage);
}
var (metadata, storage) = ReadModuleMetadataFrom(reader, kind, cancellationToken);
return (AssemblyMetadata.Create(pooledMetadata.Object), pooledStorage.Object.ToImmutableArrayOrEmpty());
pooledMetadata.Object.Add(metadata);
pooledStorage.Object.Add(storage);
}
return (AssemblyMetadata.Create(pooledMetadata.Object), pooledStorage.Object.ToImmutableArrayOrEmpty());
}
Contract.ThrowIfFalse(metadataKind == MetadataImageKind.Module);
......@@ -601,15 +595,14 @@ private static ModuleMetadata ReadModuleMetadataFrom(ObjectReader reader, Serial
if (kind == SerializationKinds.Bits)
{
storage = _storageService.CreateTemporaryStreamStorage(cancellationToken);
using (var stream = SerializableBytes.CreateWritableStream())
{
CopyByteArrayToStream(reader, stream, cancellationToken);
using var stream = SerializableBytes.CreateWritableStream();
length = stream.Length;
CopyByteArrayToStream(reader, stream, cancellationToken);
stream.Position = 0;
storage.WriteStream(stream, cancellationToken);
}
length = stream.Length;
stream.Position = 0;
storage.WriteStream(stream, cancellationToken);
return;
}
......
......@@ -90,33 +90,32 @@ public void AppendRemotableData(HashSet<Checksum> searchingChecksumsLeft, Dictio
{
// this will iterate through candidate checksums to see whether that checksum exists in both
// checksum set we are currently searching for and checksums current node contains
using (var removed = Creator.CreateList<Checksum>())
using var removed = Creator.CreateList<Checksum>();
// we have 2 sets of checksums. one we are searching for and ones this node contains.
// we only need to iterate one of them to see this node contains what we are looking for.
// so, we check two set and use one that has smaller number of checksums.
foreach (var checksum in GetSmallerChecksumList(searchingChecksumsLeft.Count, searchingChecksumsLeft, _additionalAssets.Count, _additionalAssets.Keys))
{
// we have 2 sets of checksums. one we are searching for and ones this node contains.
// we only need to iterate one of them to see this node contains what we are looking for.
// so, we check two set and use one that has smaller number of checksums.
foreach (var checksum in GetSmallerChecksumList(searchingChecksumsLeft.Count, searchingChecksumsLeft, _additionalAssets.Count, _additionalAssets.Keys))
cancellationToken.ThrowIfCancellationRequested();
// if checksumGetter return null for given checksum, that means current node doesn't have given checksum
var checksumObject = GetRemotableDataFromAdditionalAssets(checksum);
if (checksumObject != null && searchingChecksumsLeft.Contains(checksum))
{
cancellationToken.ThrowIfCancellationRequested();
// found given checksum in current node
result[checksum] = checksumObject;
removed.Object.Add(checksum);
// if checksumGetter return null for given checksum, that means current node doesn't have given checksum
var checksumObject = GetRemotableDataFromAdditionalAssets(checksum);
if (checksumObject != null && searchingChecksumsLeft.Contains(checksum))
// we found all checksums we are looking for
if (removed.Object.Count == searchingChecksumsLeft.Count)
{
// found given checksum in current node
result[checksum] = checksumObject;
removed.Object.Add(checksum);
// we found all checksums we are looking for
if (removed.Object.Count == searchingChecksumsLeft.Count)
{
break;
}
break;
}
}
searchingChecksumsLeft.ExceptWith(removed.Object);
}
searchingChecksumsLeft.ExceptWith(removed.Object);
}
private RemotableData GetRemotableDataFromAdditionalAssets(Checksum checksum)
......@@ -192,14 +191,13 @@ public RemotableData Find(Checksum checksum)
public void Append(HashSet<Checksum> searchingChecksumsLeft, Dictionary<Checksum, RemotableData> result)
{
using (var resultPool = Creator.CreateResultSet())
{
Append(searchingChecksumsLeft, resultPool.Object);
using var resultPool = Creator.CreateResultSet();
foreach (var kv in resultPool.Object)
{
result[kv.Key] = SolutionAsset.Create(kv.Key, kv.Value, _serializer);
}
Append(searchingChecksumsLeft, resultPool.Object);
foreach (var kv in resultPool.Object)
{
result[kv.Key] = SolutionAsset.Create(kv.Key, kv.Value, _serializer);
}
}
......
......@@ -100,56 +100,55 @@ public RemotableData GetRemotableData(int scopeId, Checksum checksum, Cancellati
public IReadOnlyDictionary<Checksum, RemotableData> GetRemotableData(int scopeId, IEnumerable<Checksum> checksums, CancellationToken cancellationToken)
{
using (var searchingChecksumsLeft = Creator.CreateChecksumSet(checksums))
using var searchingChecksumsLeft = Creator.CreateChecksumSet(checksums);
var numberOfChecksumsToSearch = searchingChecksumsLeft.Object.Count;
var result = new Dictionary<Checksum, RemotableData>(numberOfChecksumsToSearch);
// check nil case
if (searchingChecksumsLeft.Object.Remove(Checksum.Null))
{
var numberOfChecksumsToSearch = searchingChecksumsLeft.Object.Count;
var result = new Dictionary<Checksum, RemotableData>(numberOfChecksumsToSearch);
result[Checksum.Null] = RemotableData.Null;
}
// check nil case
if (searchingChecksumsLeft.Object.Remove(Checksum.Null))
{
result[Checksum.Null] = RemotableData.Null;
}
// search checksum trees we have
var storage = _storages[scopeId];
// search checksum trees we have
var storage = _storages[scopeId];
storage.AppendRemotableData(searchingChecksumsLeft.Object, result, cancellationToken);
if (result.Count == numberOfChecksumsToSearch)
{
// no checksum left to find
Debug.Assert(searchingChecksumsLeft.Object.Count == 0);
return result;
}
storage.AppendRemotableData(searchingChecksumsLeft.Object, result, cancellationToken);
if (result.Count == numberOfChecksumsToSearch)
{
// no checksum left to find
Debug.Assert(searchingChecksumsLeft.Object.Count == 0);
return result;
}
// search global assets
foreach (var kv in _globalAssets)
{
cancellationToken.ThrowIfCancellationRequested();
// search global assets
foreach (var kv in _globalAssets)
var asset = kv.Value;
if (searchingChecksumsLeft.Object.Remove(asset.Checksum))
{
cancellationToken.ThrowIfCancellationRequested();
result[asset.Checksum] = asset;
var asset = kv.Value;
if (searchingChecksumsLeft.Object.Remove(asset.Checksum))
if (result.Count == numberOfChecksumsToSearch)
{
result[asset.Checksum] = asset;
if (result.Count == numberOfChecksumsToSearch)
{
// no checksum left to find
Debug.Assert(searchingChecksumsLeft.Object.Count == 0);
return result;
}
// no checksum left to find
Debug.Assert(searchingChecksumsLeft.Object.Count == 0);
return result;
}
}
}
// if it reached here, it means things get cancelled. due to involving 2 processes,
// current design can make slightly staled requests to running even when things cancelled.
// if it is other case, remote host side will throw and close connection which will cause
// vs to crash.
// this should be changed once I address this design issue
cancellationToken.ThrowIfCancellationRequested();
// if it reached here, it means things get cancelled. due to involving 2 processes,
// current design can make slightly staled requests to running even when things cancelled.
// if it is other case, remote host side will throw and close connection which will cause
// vs to crash.
// this should be changed once I address this design issue
cancellationToken.ThrowIfCancellationRequested();
return result;
}
return result;
}
public void RegisterSnapshot(PinnedRemotableDataScope scope, AssetStorages.Storage storage)
......
......@@ -41,13 +41,12 @@ public override Task WriteObjectToAsync(ObjectWriter writer, CancellationToken c
private static Checksum CreateChecksumFromStreamWriter(WellKnownSynchronizationKind kind, Action<ObjectWriter, CancellationToken> writer)
{
using (var stream = SerializableBytes.CreateWritableStream())
using (var objectWriter = new ObjectWriter(stream))
{
objectWriter.WriteInt32((int)kind);
writer(objectWriter, CancellationToken.None);
return Checksum.Create(stream);
}
using var stream = SerializableBytes.CreateWritableStream();
using var objectWriter = new ObjectWriter(stream);
objectWriter.WriteInt32((int)kind);
writer(objectWriter, CancellationToken.None);
return Checksum.Create(stream);
}
}
......
......@@ -84,93 +84,92 @@ private T GetSmallestContainingIntervalWorker(int start, int length, Func<T, int
// contains the given "span"
// 4. move up the spin until it finds one that contains the "span" which should be smallest span that contains the given "span"
// 5. if it is going up from right side, it make sure to check left side of tree first.
using (var pooledObject = SharedPools.Default<Stack<Node>>().GetPooledObject())
using var pooledObject = SharedPools.Default<Stack<Node>>().GetPooledObject();
var spineNodes = pooledObject.Object;
spineNodes.Push(root);
while (spineNodes.Count > 0)
{
var spineNodes = pooledObject.Object;
var currentNode = spineNodes.Peek();
// only goes to right if right tree contains given span
if (Introspector.GetStart(currentNode.Value) <= start)
{
var right = currentNode.Right;
if (right != null && end < MaxEndValue(right))
{
spineNodes.Push(right);
continue;
}
}
spineNodes.Push(root);
// right side, sub tree doesn't contain the given span, put current node on
// stack, and move down to left sub tree
var left = currentNode.Left;
if (left != null && end <= MaxEndValue(left))
{
spineNodes.Push(left);
continue;
}
// we reached the point, where we can't go down anymore.
// now, go back up to find best answer
while (spineNodes.Count > 0)
{
var currentNode = spineNodes.Peek();
currentNode = spineNodes.Pop();
// only goes to right if right tree contains given span
if (Introspector.GetStart(currentNode.Value) <= start)
// check whether current node meets condition
if (predicate(currentNode.Value, start, length))
{
var right = currentNode.Right;
if (right != null && end < MaxEndValue(right))
// hold onto best answer
if (EqualityComparer<T>.Default.Equals(result, default) ||
(Introspector.GetStart(result) <= Introspector.GetStart(currentNode.Value) &&
Introspector.GetLength(currentNode.Value) < Introspector.GetLength(result)))
{
spineNodes.Push(right);
continue;
result = currentNode.Value;
}
}
// right side, sub tree doesn't contain the given span, put current node on
// stack, and move down to left sub tree
var left = currentNode.Left;
if (left != null && end <= MaxEndValue(left))
// there is no parent, result we currently have is the best answer
if (spineNodes.Count == 0)
{
spineNodes.Push(left);
continue;
return result;
}
// we reached the point, where we can't go down anymore.
// now, go back up to find best answer
while (spineNodes.Count > 0)
var parentNode = spineNodes.Peek();
// if we are under left side of parent node
if (parentNode.Left == currentNode)
{
currentNode = spineNodes.Pop();
// go one level up again
continue;
}
// check whether current node meets condition
if (predicate(currentNode.Value, start, length))
// okay, we are under right side of parent node
if (parentNode.Right == currentNode)
{
// try left side of parent node if it can have better answer
if (parentNode.Left != null && end <= MaxEndValue(parentNode.Left))
{
// hold onto best answer
// right side tree doesn't have any answer or if the right side has
// an answer but left side can have better answer then try left side
if (EqualityComparer<T>.Default.Equals(result, default) ||
(Introspector.GetStart(result) <= Introspector.GetStart(currentNode.Value) &&
Introspector.GetLength(currentNode.Value) < Introspector.GetLength(result)))
Introspector.GetStart(parentNode.Value) == Introspector.GetStart(currentNode.Value))
{
result = currentNode.Value;
// put left as new root, and break out inner loop
spineNodes.Push(parentNode.Left);
break;
}
}
// there is no parent, result we currently have is the best answer
if (spineNodes.Count == 0)
{
return result;
}
var parentNode = spineNodes.Peek();
// if we are under left side of parent node
if (parentNode.Left == currentNode)
{
// go one level up again
continue;
}
// okay, we are under right side of parent node
if (parentNode.Right == currentNode)
{
// try left side of parent node if it can have better answer
if (parentNode.Left != null && end <= MaxEndValue(parentNode.Left))
{
// right side tree doesn't have any answer or if the right side has
// an answer but left side can have better answer then try left side
if (EqualityComparer<T>.Default.Equals(result, default) ||
Introspector.GetStart(parentNode.Value) == Introspector.GetStart(currentNode.Value))
{
// put left as new root, and break out inner loop
spineNodes.Push(parentNode.Left);
break;
}
}
// no left side, go one more level up
continue;
}
// no left side, go one more level up
continue;
}
}
return result;
}
return result;
}
#if DEBUG
......
......@@ -94,19 +94,18 @@ private SyntaxNode CreateFormattedRoot(CancellationToken cancellationToken)
var changes = GetChanges(cancellationToken);
// create a map
using (var pooledObject = SharedPools.Default<Dictionary<ValueTuple<SyntaxToken, SyntaxToken>, TriviaData>>().GetPooledObject())
{
var map = pooledObject.Object;
changes.Do(change => map.Add(change.Item1, change.Item2));
using var pooledObject = SharedPools.Default<Dictionary<ValueTuple<SyntaxToken, SyntaxToken>, TriviaData>>().GetPooledObject();
// no changes, return as it is.
if (map.Count == 0)
{
return this.TreeInfo.Root;
}
var map = pooledObject.Object;
changes.Do(change => map.Add(change.Item1, change.Item2));
return Rewriter(map, cancellationToken);
// no changes, return as it is.
if (map.Count == 0)
{
return this.TreeInfo.Root;
}
return Rewriter(map, cancellationToken);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册