diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index a231e5267c74e..a9da3ca0a1c68 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -7,9 +7,9 @@
https://github.com/dotnet/arcade
ed69753a3ffbdaa08365252c710d57a64d17f859
-
+
https://github.com/dotnet/roslyn
- 09f75b83754732a74e0815976b80ecffd94c0dde
+ f24d2c5c98211908ab90d6f1f42e7592411d6058
diff --git a/eng/Versions.props b/eng/Versions.props
index 24807bc01d808..2c7f6622ae35e 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -23,7 +23,7 @@
- 3.8.0-1.20353.1
+ 3.8.0-1.20361.1
diff --git a/eng/config/PublishData.json b/eng/config/PublishData.json
index 31f2c14b3ddad..42f0663819b97 100644
--- a/eng/config/PublishData.json
+++ b/eng/config/PublishData.json
@@ -185,12 +185,12 @@
"vsBranch": "master",
"vsMajorVersion": 16
},
- "features/dotnetFormat": {
+ "features/UsedAssemblyReferences": {
"nugetKind": [ "Shipping", "NonShipping" ],
- "version": "3.3.*",
+ "version": "3.8.*",
"nuget": [ "https://dotnet.myget.org/F/roslyn/api/v2/package" ],
"vsix": [ "https://dotnet.myget.org/F/roslyn/vsix/upload" ],
- "channels": [ "dotnetFormat" ],
+ "channels": [ "UsedAssemblyReferences" ],
"vsBranch": "master",
"vsMajorVersion": 16
},
diff --git a/src/Compilers/Core/CommandLine/BuildProtocol.cs b/src/Compilers/Core/CommandLine/BuildProtocol.cs
index 0a20e7f6db16b..f0389f538128d 100644
--- a/src/Compilers/Core/CommandLine/BuildProtocol.cs
+++ b/src/Compilers/Core/CommandLine/BuildProtocol.cs
@@ -82,11 +82,12 @@ public static BuildRequest Create(RequestLanguage language,
{
Debug.Assert(!string.IsNullOrWhiteSpace(compilerHash), "CompilerHash is required to send request to the build server");
- Log("Creating BuildRequest");
- Log($"Working directory: {workingDirectory}");
- Log($"Temp directory: {tempDirectory}");
- Log($"Lib directory: {libDirectory ?? "null"}");
- Log($"Compiler hash: {compilerHash}");
+ Log($@"
+Creating BuildRequest
+ Working directory: {workingDirectory}
+ Temp directory: {tempDirectory}
+ Lib directory: {libDirectory ?? null}
+ Compiler hash: {compilerHash}");
var requestLength = args.Count + 1 + (libDirectory == null ? 0 : 1);
var requestArgs = new List(requestLength);
@@ -108,7 +109,6 @@ public static BuildRequest Create(RequestLanguage language,
for (int i = 0; i < args.Count; ++i)
{
var arg = args[i];
- Log($"argument[{i}] = {arg}");
requestArgs.Add(new Argument(ArgumentId.CommandLineArgument, i, arg));
}
@@ -118,7 +118,7 @@ public static BuildRequest Create(RequestLanguage language,
public static BuildRequest CreateShutdown()
{
var requestArgs = new[] { new Argument(ArgumentId.Shutdown, argumentIndex: 0, value: "") };
- return new BuildRequest(BuildProtocolConstants.ProtocolVersion, RequestLanguage.CSharpCompile, GetCommitHash(), requestArgs);
+ return new BuildRequest(BuildProtocolConstants.ProtocolVersion, RequestLanguage.CSharpCompile, GetCommitHash() ?? "", requestArgs);
}
///
@@ -127,19 +127,17 @@ public static BuildRequest CreateShutdown()
/// The total request size must be less than 1MB.
///
/// null if the Request was too large, the Request otherwise.
- public static async Task ReadAsync(Stream inStream, CancellationToken cancellationToken)
+ public static async Task ReadAsync(Stream inStream, CancellationToken cancellationToken)
{
// Read the length of the request
var lengthBuffer = new byte[4];
- Log("Reading length of request");
await ReadAllAsync(inStream, lengthBuffer, 4, cancellationToken).ConfigureAwait(false);
var length = BitConverter.ToInt32(lengthBuffer, 0);
// Back out if the request is > 1MB
if (length > 0x100000)
{
- Log("Request is over 1MB in length, cancelling read.");
- return null;
+ throw new ArgumentException("Request is over 1MB in length");
}
cancellationToken.ThrowIfCancellationRequested();
@@ -150,7 +148,6 @@ public static BuildRequest CreateShutdown()
cancellationToken.ThrowIfCancellationRequested();
- Log("Parsing request");
// Parse the request into the Request data structure.
using (var reader = new BinaryReader(new MemoryStream(requestBuffer), Encoding.Unicode))
{
@@ -182,8 +179,6 @@ public static BuildRequest CreateShutdown()
using (var memoryStream = new MemoryStream())
using (var writer = new BinaryWriter(memoryStream, Encoding.Unicode))
{
- // Format the request.
- Log("Formatting request");
writer.Write(ProtocolVersion);
writer.Write((uint)Language);
writer.Write(CompilerHash);
@@ -203,17 +198,12 @@ public static BuildRequest CreateShutdown()
// Back out if the request is > 1 MB
if (memoryStream.Length > 0x100000)
{
- Log("Request is over 1MB in length, cancelling write");
- throw new ArgumentOutOfRangeException();
+ throw new ArgumentOutOfRangeException("Request is over 1MB in length");
}
- // Send the request to the server
- Log("Writing length of request.");
await outStream.WriteAsync(BitConverter.GetBytes(length), 0, 4,
cancellationToken).ConfigureAwait(false);
- Log("Writing request of size {0}", length);
- // Write the request
memoryStream.Position = 0;
await memoryStream.CopyToAsync(outStream, bufferSize: length, cancellationToken: cancellationToken).ConfigureAwait(false);
}
@@ -311,8 +301,6 @@ public async Task WriteAsync(Stream outStream,
using (var memoryStream = new MemoryStream())
using (var writer = new BinaryWriter(memoryStream, Encoding.Unicode))
{
- // Format the response
- Log("Formatting Response");
writer.Write((int)Type);
AddResponseBody(writer);
@@ -325,7 +313,6 @@ public async Task WriteAsync(Stream outStream,
// Write the length of the response
int length = checked((int)memoryStream.Length);
- Log("Writing response length");
// There is no way to know the number of bytes written to
// the pipe stream. We just have to assume all of them are written.
await outStream.WriteAsync(BitConverter.GetBytes(length),
@@ -333,8 +320,6 @@ await outStream.WriteAsync(BitConverter.GetBytes(length),
4,
cancellationToken).ConfigureAwait(false);
- // Write the response
- Log("Writing response of size {0}", length);
memoryStream.Position = 0;
await memoryStream.CopyToAsync(outStream, bufferSize: length, cancellationToken: cancellationToken).ConfigureAwait(false);
}
@@ -350,14 +335,12 @@ await outStream.WriteAsync(BitConverter.GetBytes(length),
///
public static async Task ReadAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken))
{
- Log("Reading response length");
// Read the response length
var lengthBuffer = new byte[4];
await ReadAllAsync(stream, lengthBuffer, 4, cancellationToken).ConfigureAwait(false);
var length = BitConverter.ToUInt32(lengthBuffer, 0);
// Read the response
- Log("Reading response of length {0}", length);
var responseBuffer = new byte[length];
await ReadAllAsync(stream,
responseBuffer,
@@ -381,7 +364,7 @@ await ReadAllAsync(stream,
case ResponseType.Shutdown:
return ShutdownBuildResponse.Create(reader);
case ResponseType.Rejected:
- return new RejectedBuildResponse();
+ return RejectedBuildResponse.Create(reader);
default:
throw new InvalidOperationException("Received invalid response type from server.");
}
@@ -505,13 +488,30 @@ protected override void AddResponseBody(BinaryWriter writer) { }
internal sealed class RejectedBuildResponse : BuildResponse
{
+ public string Reason;
+
public override ResponseType Type => ResponseType.Rejected;
+ public RejectedBuildResponse(string reason)
+ {
+ Reason = reason;
+ }
+
///
/// AnalyzerInconsistency has no body.
///
///
- protected override void AddResponseBody(BinaryWriter writer) { }
+ protected override void AddResponseBody(BinaryWriter writer)
+ {
+ WriteLengthPrefixedString(writer, Reason);
+ }
+
+ public static RejectedBuildResponse Create(BinaryReader reader)
+ {
+ var reason = ReadLengthPrefixedString(reader);
+ Debug.Assert(reason is object);
+ return new RejectedBuildResponse(reason);
+ }
}
// The id numbers below are just random. It's useful to use id numbers
@@ -592,14 +592,13 @@ public static void WriteLengthPrefixedString(BinaryWriter writer, string? value)
/// Reads the value of of the assembly is defined in
///
/// The hash value of the current assembly or an empty string
- public static string GetCommitHash()
+ public static string? GetCommitHash()
{
var hashAttributes = typeof(BuildRequest).Assembly.GetCustomAttributes();
var hashAttributeCount = hashAttributes.Count();
if (hashAttributeCount != 1)
{
- Log($"Error reading CommitHashAttribute. Exactly 1 attribute is required, found {hashAttributeCount}");
- return string.Empty;
+ return null;
}
return hashAttributes.Single().Hash;
}
@@ -616,21 +615,16 @@ internal static async Task ReadAllAsync(
int totalBytesRead = 0;
do
{
- Log("Attempting to read {0} bytes from the stream",
- count - totalBytesRead);
int bytesRead = await stream.ReadAsync(buffer,
totalBytesRead,
count - totalBytesRead,
cancellationToken).ConfigureAwait(false);
if (bytesRead == 0)
{
- Log("Unexpected -- read 0 bytes from the stream.");
throw new EndOfStreamException("Reached end of stream before end of read.");
}
- Log("Read {0} bytes", bytesRead);
totalBytesRead += bytesRead;
} while (totalBytesRead < count);
- Log("Finished read");
}
}
}
diff --git a/src/Compilers/Server/VBCSCompiler/CompilerRequestHandler.cs b/src/Compilers/Server/VBCSCompiler/CompilerRequestHandler.cs
index 559c97032114d..c8865427d463f 100644
--- a/src/Compilers/Server/VBCSCompiler/CompilerRequestHandler.cs
+++ b/src/Compilers/Server/VBCSCompiler/CompilerRequestHandler.cs
@@ -96,27 +96,22 @@ public bool TryCreateCompiler(RunRequest request, out CommonCompiler compiler)
public BuildResponse RunCompilation(RunRequest request, CancellationToken cancellationToken)
{
- Log($"CurrentDirectory = '{request.CurrentDirectory}'");
- Log($"LIB = '{request.LibDirectory}'");
- for (int i = 0; i < request.Arguments.Length; ++i)
- {
- Log($"Argument[{i}] = '{request.Arguments[i]}'");
- }
+ Log($@"
+Run Compilation
+ CurrentDirectory = '{request.CurrentDirectory}
+ LIB = '{request.LibDirectory}'");
// Compiler server must be provided with a valid temporary directory in order to correctly
// isolate signing between compilations.
if (string.IsNullOrEmpty(request.TempDirectory))
{
- Log($"Rejecting build due to missing temp directory");
- return new RejectedBuildResponse();
+ return new RejectedBuildResponse("Missing temp directory");
}
CommonCompiler compiler;
if (!TryCreateCompiler(request, out compiler))
{
- // We can't do anything with a request we don't know about.
- Log($"Got request with id '{request.Language}'");
- return new RejectedBuildResponse();
+ return new RejectedBuildResponse($"Cannot create compiler for language id {request.Language}");
}
bool utf8output = compiler.Arguments.Utf8Output;
@@ -125,11 +120,16 @@ public BuildResponse RunCompilation(RunRequest request, CancellationToken cancel
return new AnalyzerInconsistencyBuildResponse();
}
- Log($"****Running {request.Language} compiler...");
+ Log($"Begin {request.Language} compiler run");
TextWriter output = new StringWriter(CultureInfo.InvariantCulture);
int returnCode = compiler.Run(output, cancellationToken);
- Log($"****{request.Language} Compilation complete.\r\n****Return code: {returnCode}\r\n****Output:\r\n{output.ToString()}\r\n");
- return new CompletedBuildResponse(returnCode, utf8output, output.ToString());
+ var outputString = output.ToString();
+ Log(@$"
+End {request.Language} Compilation complete.
+Return code: {returnCode}
+Output:
+{outputString}");
+ return new CompletedBuildResponse(returnCode, utf8output, outputString);
}
}
}
diff --git a/src/Compilers/Server/VBCSCompiler/NamedPipeClientConnection.cs b/src/Compilers/Server/VBCSCompiler/NamedPipeClientConnection.cs
index 35e1a5597e1b6..1605bf4624905 100644
--- a/src/Compilers/Server/VBCSCompiler/NamedPipeClientConnection.cs
+++ b/src/Compilers/Server/VBCSCompiler/NamedPipeClientConnection.cs
@@ -112,8 +112,7 @@ public void Close()
// The client connection failing to close isn't fatal to the server process. It is simply a client
// for which we can no longer communicate and that's okay because the Close method indicates we are
// done with the client already.
- var msg = string.Format($"Pipe {LoggingIdentifier}: Error closing pipe.");
- CompilerServerLogger.LogException(e, msg);
+ CompilerServerLogger.LogException(e, $"Pipe {LoggingIdentifier}: Error closing pipe.");
}
}
@@ -124,14 +123,12 @@ public void Close()
BuildRequest request;
try
{
- Log("Begin reading request.");
request = await BuildRequest.ReadAsync(_stream, cancellationToken).ConfigureAwait(false);
ValidateBuildRequest(request);
- Log("End reading request.");
}
catch (Exception e)
{
- LogException(e, "Error reading build request.");
+ CompilerServerLogger.LogException(e, "Error reading build request.");
return new ConnectionData(CompletionReason.CompilationNotStarted);
}
@@ -149,7 +146,7 @@ public void Close()
}
else if (!allowCompilationRequests)
{
- return await HandleRejectedRequestAsync(cancellationToken).ConfigureAwait(false);
+ return await HandleRejectedRequestAsync("Compilation requests not allowed at this time", cancellationToken).ConfigureAwait(false);
}
else
{
@@ -181,10 +178,8 @@ private async Task HandleCompilationRequestAsync(BuildRequest re
try
{
- Log("Begin writing response.");
await response.WriteAsync(_stream, cancellationToken).ConfigureAwait(false);
reason = CompletionReason.CompilationCompleted;
- Log("End writing response.");
}
catch
{
@@ -216,9 +211,9 @@ private async Task HandleIncorrectHashRequestAsync(CancellationT
return new ConnectionData(CompletionReason.CompilationNotStarted);
}
- private async Task HandleRejectedRequestAsync(CancellationToken cancellationToken)
+ private async Task HandleRejectedRequestAsync(string reason, CancellationToken cancellationToken)
{
- var response = new RejectedBuildResponse();
+ var response = new RejectedBuildResponse(reason);
await response.WriteAsync(_stream, cancellationToken).ConfigureAwait(false);
return new ConnectionData(CompletionReason.CompilationNotStarted);
}
@@ -266,13 +261,8 @@ private Task ServeBuildRequestAsync(BuildRequest buildRequest, Ca
{
Func func = () =>
{
- // Do the compilation
- Log("Begin compilation");
-
var request = BuildProtocolUtil.GetRunRequest(buildRequest);
var response = _compilerServerHost.RunCompilation(request, cancellationToken);
-
- Log("End compilation");
return response;
};
@@ -280,15 +270,5 @@ private Task ServeBuildRequestAsync(BuildRequest buildRequest, Ca
task.Start();
return task;
}
-
- private void Log(string message)
- {
- CompilerServerLogger.Log("Client {0}: {1}", _loggingIdentifier, message);
- }
-
- private void LogException(Exception e, string message)
- {
- CompilerServerLogger.LogException(e, string.Format("Client {0}: {1}", _loggingIdentifier, message));
- }
}
}
diff --git a/src/Compilers/Server/VBCSCompiler/ServerDispatcher.cs b/src/Compilers/Server/VBCSCompiler/ServerDispatcher.cs
index 762a7457559fa..4a7039c97e69d 100644
--- a/src/Compilers/Server/VBCSCompiler/ServerDispatcher.cs
+++ b/src/Compilers/Server/VBCSCompiler/ServerDispatcher.cs
@@ -229,6 +229,7 @@ private void HandleCompletedListenTask(CancellationToken cancellationToken)
private void HandleCompletedTimeoutTask()
{
+ CompilerServerLogger.Log("Timeout triggered. Shutting down server.");
_diagnosticListener.KeepAliveReached();
_listenCancellationTokenSource.Cancel();
_timeoutTask = null;
@@ -298,10 +299,12 @@ private void HandleCompletedConnections()
case CompletionReason.ClientDisconnect:
// Have to assume the worst here which is user pressing Ctrl+C at the command line and
// hence wanting all compilation to end.
+ CompilerServerLogger.Log("Unexpected client disconnect. Shutting down server");
shutdown = true;
break;
case CompletionReason.ClientException:
case CompletionReason.ClientShutdownRequest:
+ CompilerServerLogger.Log($"Unexpected client completion: {connectionData.CompletionReason}. Shutting down server");
shutdown = true;
break;
default:
diff --git a/src/Compilers/Server/VBCSCompilerTests/CompilerServerApiTest.cs b/src/Compilers/Server/VBCSCompilerTests/CompilerServerApiTest.cs
index 1299275b4c5a7..e101d9bdd63ea 100644
--- a/src/Compilers/Server/VBCSCompilerTests/CompilerServerApiTest.cs
+++ b/src/Compilers/Server/VBCSCompilerTests/CompilerServerApiTest.cs
@@ -512,7 +512,7 @@ public async Task CancelWillCancelCompilation()
}
cancellationToken.WaitHandle.WaitOne();
- return new RejectedBuildResponse();
+ return new RejectedBuildResponse("");
};
var list = new List>();
diff --git a/src/Compilers/Shared/BuildServerConnection.cs b/src/Compilers/Shared/BuildServerConnection.cs
index a6081eb936bd6..17d308b92b369 100644
--- a/src/Compilers/Shared/BuildServerConnection.cs
+++ b/src/Compilers/Shared/BuildServerConnection.cs
@@ -113,14 +113,14 @@ internal static async Task RunServerCompilationCoreAsync(
CreateServerFunc createServerFunc,
CancellationToken cancellationToken)
{
- if (pipeName == null)
+ if (pipeName is null)
{
- return new RejectedBuildResponse();
+ throw new ArgumentException(nameof(pipeName));
}
if (buildPaths.TempDirectory == null)
{
- return new RejectedBuildResponse();
+ throw new ArgumentException(nameof(buildPaths));
}
// early check for the build hash. If we can't find it something is wrong; no point even trying to go to the server
@@ -132,21 +132,21 @@ internal static async Task RunServerCompilationCoreAsync(
var pipeTask = tryConnectToServer(pipeName, buildPaths, timeoutOverride, createServerFunc, cancellationToken);
if (pipeTask is null)
{
- return new RejectedBuildResponse();
+ return new RejectedBuildResponse("Failed to connect to server");
}
else
{
var pipe = await pipeTask.ConfigureAwait(false);
if (pipe is null)
{
- return new RejectedBuildResponse();
+ return new RejectedBuildResponse("Failed to connect to server");
}
else
{
var request = BuildRequest.Create(language,
buildPaths.WorkingDirectory,
buildPaths.TempDirectory,
- BuildProtocolConstants.GetCommitHash(),
+ BuildProtocolConstants.GetCommitHash() ?? "",
arguments,
keepAlive,
libEnvVariable);
@@ -259,7 +259,7 @@ private static async Task TryCompileAsync(NamedPipeClientStream p
catch (Exception e)
{
LogException(e, "Error writing build request.");
- return new RejectedBuildResponse();
+ return new RejectedBuildResponse($"Error writing build request: {e.Message}");
}
// Wait for the compilation and a monitor to detect if the server disconnects
@@ -283,13 +283,13 @@ private static async Task TryCompileAsync(NamedPipeClientStream p
catch (Exception e)
{
LogException(e, "Error reading response");
- response = new RejectedBuildResponse();
+ response = new RejectedBuildResponse($"Error reading response: {e.Message}");
}
}
else
{
- Log("Server disconnect");
- response = new RejectedBuildResponse();
+ Log("Client disconnect");
+ response = new RejectedBuildResponse($"Client disconnected");
}
// Cancel whatever task is still around
diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpReplIdeFeatures.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpReplIdeFeatures.cs
index 64d7d33446a7e..a31eb5206ddfe 100644
--- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpReplIdeFeatures.cs
+++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpReplIdeFeatures.cs
@@ -88,7 +88,7 @@ public void HighlightRefsSingleSubmissionVerifyRenameTagsGoAway()
VisualStudio.InteractiveWindow.VerifyTags(WellKnownTagNames.MarkerFormatDefinition_HighlightedWrittenReference, 0);
}
- [WpfFact]
+ [WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/46027")]
public void HighlightRefsMultipleSubmisionsVerifyRenameTagsShowUpWhenInvokedOnSubmittedText()
{
VisualStudio.InteractiveWindow.SubmitText("class Goo { }");
@@ -100,7 +100,7 @@ public void HighlightRefsMultipleSubmisionsVerifyRenameTagsShowUpWhenInvokedOnSu
VisualStudio.InteractiveWindow.VerifyTags(WellKnownTagNames.MarkerFormatDefinition_HighlightedReference, 1);
}
- [WpfFact]
+ [WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/46027")]
public void HighlightRefsMultipleSubmisionsVerifyRenameTagsShowUpOnUnsubmittedText()
{
VisualStudio.InteractiveWindow.SubmitText("class Goo { }");
@@ -112,7 +112,7 @@ public void HighlightRefsMultipleSubmisionsVerifyRenameTagsShowUpOnUnsubmittedTe
VisualStudio.InteractiveWindow.VerifyTags(WellKnownTagNames.MarkerFormatDefinition_HighlightedReference, 1);
}
- [WpfFact]
+ [WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/46027")]
public void HighlightRefsMultipleSubmisionsVerifyRenameTagsShowUpOnTypesWhenInvokedOnSubmittedText()
{
VisualStudio.InteractiveWindow.SubmitText("class Goo { }");
@@ -124,7 +124,7 @@ public void HighlightRefsMultipleSubmisionsVerifyRenameTagsShowUpOnTypesWhenInvo
VisualStudio.InteractiveWindow.VerifyTags(WellKnownTagNames.MarkerFormatDefinition_HighlightedReference, 2);
}
- [WpfFact]
+ [WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/46027")]
public void HighlightRefsMultipleSubmisionsVerifyRenameTagsShowUpOnTypesWhenInvokedOnUnsubmittedText()
{
VisualStudio.InteractiveWindow.SubmitText("class Goo { }");
diff --git a/src/Workspaces/Core/Portable/Remote/RemoteArguments.cs b/src/Workspaces/Core/Portable/Remote/RemoteArguments.cs
index 7ca3ced163be6..f6c6378b82147 100644
--- a/src/Workspaces/Core/Portable/Remote/RemoteArguments.cs
+++ b/src/Workspaces/Core/Portable/Remote/RemoteArguments.cs
@@ -107,14 +107,14 @@ public async Task TryRehydrateAsync(
// The server and client should both be talking about the same compilation. As such
// locations in symbols are save to resolve as we rehydrate the SymbolKey.
var symbol = SymbolKey.ResolveString(
- SymbolKeyData, compilation, cancellationToken: cancellationToken).GetAnySymbol();
+ SymbolKeyData, compilation, out var failureReason, cancellationToken).GetAnySymbol();
if (symbol == null)
{
try
{
throw new InvalidOperationException(
- $"We should always be able to resolve a symbol back on the host side:\r\n{SymbolKeyData}");
+ $"We should always be able to resolve a symbol back on the host side:\r\n{SymbolKeyData}\r\n{failureReason}");
}
catch (Exception ex) when (FatalError.ReportWithoutCrash(ex))
{
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.AliasSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.AliasSymbolKey.cs
index 16c62ad938634..d4b6bd9caa68a 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.AliasSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.AliasSymbolKey.cs
@@ -18,12 +18,18 @@ public static void Create(IAliasSymbol symbol, SymbolKeyWriter visitor)
visitor.WriteString(FirstOrDefault(symbol.DeclaringSyntaxReferences)?.SyntaxTree.FilePath ?? "");
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
var name = reader.ReadString();
- var targetResolution = reader.ReadSymbolKey();
+ var targetResolution = reader.ReadSymbolKey(out var targetFailureReason);
var filePath = reader.ReadString();
+ if (targetFailureReason != null)
+ {
+ failureReason = $"({nameof(AliasSymbolKey)} {nameof(targetResolution)} failed -> {targetFailureReason})";
+ return default;
+ }
+
var syntaxTree = reader.GetSyntaxTree(filePath);
if (syntaxTree != null)
{
@@ -34,11 +40,13 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
var result = Resolve(semanticModel, syntaxTree.GetRoot(reader.CancellationToken), name, target, reader.CancellationToken);
if (result.HasValue)
{
+ failureReason = null;
return result.Value;
}
}
}
+ failureReason = $"({nameof(AliasSymbolKey)} '{name}' not found)";
return default;
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.AnonymousFunctionOrDelegateSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.AnonymousFunctionOrDelegateSymbolKey.cs
index 9e37a9aad8a6c..f2fdae2dbaf9f 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.AnonymousFunctionOrDelegateSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.AnonymousFunctionOrDelegateSymbolKey.cs
@@ -31,14 +31,21 @@ public static void Create(ISymbol symbol, SymbolKeyWriter visitor)
visitor.WriteLocation(FirstOrDefault(symbol.Locations));
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
var isAnonymousDelegateType = reader.ReadBoolean();
- var location = reader.ReadLocation();
+ var location = reader.ReadLocation(out var locationFailureReason);
+
+ if (locationFailureReason != null)
+ {
+ failureReason = $"({nameof(AnonymousFunctionOrDelegateSymbolKey)} {nameof(location)} failed -> {locationFailureReason})";
+ return default;
+ }
var syntaxTree = location.SourceTree;
if (syntaxTree == null)
{
+ failureReason = $"({nameof(AnonymousFunctionOrDelegateSymbolKey)} {nameof(SyntaxTree)} failed)";
return default;
}
@@ -58,6 +65,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
symbol = anonymousDelegate;
}
+ failureReason = null;
return new SymbolKeyResolution(symbol);
}
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.AnonymousTypeSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.AnonymousTypeSymbolKey.cs
index 1482acb3cd495..b9408cc4565a1 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.AnonymousTypeSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.AnonymousTypeSymbolKey.cs
@@ -28,12 +28,24 @@ public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor)
visitor.WriteLocationArray(propertyLocations);
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
- using var propertyTypes = reader.ReadSymbolKeyArray();
+ using var propertyTypes = reader.ReadSymbolKeyArray(out var propertyTypesFailureReason);
using var propertyNames = reader.ReadStringArray();
using var propertyIsReadOnly = reader.ReadBooleanArray();
- using var propertyLocations = reader.ReadLocationArray();
+ using var propertyLocations = reader.ReadLocationArray(out var propertyLocationsFailureReason);
+
+ if (propertyTypesFailureReason != null)
+ {
+ failureReason = $"({nameof(AnonymousTypeSymbolKey)} {nameof(propertyTypes)} failed -> {propertyTypesFailureReason})";
+ return default;
+ }
+
+ if (propertyLocationsFailureReason != null)
+ {
+ failureReason = $"({nameof(AnonymousTypeSymbolKey)} {nameof(propertyLocations)} failed -> {propertyLocationsFailureReason})";
+ return default;
+ }
if (!propertyTypes.IsDefault)
{
@@ -42,6 +54,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
var anonymousType = reader.Compilation.CreateAnonymousTypeSymbol(
propertyTypes.ToImmutable(), propertyNames.ToImmutable(),
propertyIsReadOnly.ToImmutable(), propertyLocations.ToImmutable());
+ failureReason = null;
return new SymbolKeyResolution(anonymousType);
}
catch (ArgumentException)
@@ -49,6 +62,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
}
}
+ failureReason = null;
return new SymbolKeyResolution(reader.Compilation.ObjectType);
}
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ArrayTypeSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ArrayTypeSymbolKey.cs
index 2cbbfa3dccbe3..28a9eab15747d 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ArrayTypeSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ArrayTypeSymbolKey.cs
@@ -14,18 +14,22 @@ public static void Create(IArrayTypeSymbol symbol, SymbolKeyWriter visitor)
visitor.WriteInteger(symbol.Rank);
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
- var elementTypeResolution = reader.ReadSymbolKey();
+ var elementTypeResolution = reader.ReadSymbolKey(out var elementTypeFailureReason);
var rank = reader.ReadInteger();
+ if (elementTypeFailureReason != null)
+ {
+ failureReason = $"({nameof(ArrayTypeSymbolKey)} {nameof(elementTypeResolution)} failed -> {elementTypeFailureReason})";
+ return default;
+ }
+
using var result = PooledArrayBuilder.GetInstance(elementTypeResolution.SymbolCount);
foreach (var typeSymbol in elementTypeResolution.OfType())
- {
result.AddIfNotNull(reader.Compilation.CreateArrayTypeSymbol(typeSymbol, rank));
- }
- return CreateResolution(result);
+ return CreateResolution(result, $"({nameof(ArrayTypeSymbolKey)})", out failureReason);
}
}
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.AssemblySymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.AssemblySymbolKey.cs
index 972480399850c..c86d0720bc2c7 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.AssemblySymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.AssemblySymbolKey.cs
@@ -17,7 +17,7 @@ public static void Create(IAssemblySymbol symbol, SymbolKeyWriter visitor)
visitor.WriteString(symbol.Identity.Name);
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
var assemblyName = reader.ReadString();
var compilation = reader.Compilation;
@@ -38,7 +38,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
}
}
- return CreateResolution(result);
+ return CreateResolution(result, $"({nameof(AssemblySymbolKey)} '{assemblyName}' not found)", out failureReason);
}
}
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs
index 4be5bdc419dda..1b662ffb0fdd4 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs
@@ -116,15 +116,21 @@ private static bool TryGetSemanticModel(
return false;
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var cancellationToken = reader.CancellationToken;
var name = reader.ReadString();
var kind = (SymbolKind)reader.ReadInteger();
- var locations = reader.ReadLocationArray();
+ var locations = reader.ReadLocationArray(out var locationsFailureReason);
var ordinal = reader.ReadInteger();
+ if (locationsFailureReason != null)
+ {
+ failureReason = $"({nameof(BodyLevelSymbolKey)} {nameof(locations)} failed -> {locationsFailureReason})";
+ return default;
+ }
+
// First check if we can recover the symbol just through the original location.
foreach (var loc in locations)
{
@@ -136,6 +142,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
if (symbol?.Kind == kind &&
SymbolKey.Equals(reader.Compilation, name, symbol.Name))
{
+ failureReason = null;
return resolution;
}
}
@@ -148,10 +155,14 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
foreach (var symbol in EnumerateSymbols(semanticModel, kind, name, cancellationToken))
{
if (symbol.ordinal == ordinal)
+ {
+ failureReason = null;
return new SymbolKeyResolution(symbol.symbol);
+ }
}
}
+ failureReason = $"({nameof(BodyLevelSymbolKey)} '{name}' not found)";
return default;
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.DynamicTypeSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.DynamicTypeSymbolKey.cs
index 8423b72ae372b..90a12bac68ff1 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.DynamicTypeSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.DynamicTypeSymbolKey.cs
@@ -14,8 +14,11 @@ public static void Create(SymbolKeyWriter _)
// per compilation.
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
- => new SymbolKeyResolution(reader.Compilation.DynamicType);
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
+ {
+ failureReason = null;
+ return new SymbolKeyResolution(reader.Compilation.DynamicType);
+ }
}
}
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ErrorTypeSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ErrorTypeSymbolKey.cs
index 387fe6987b81d..7db7c6f7b48a0 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ErrorTypeSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ErrorTypeSymbolKey.cs
@@ -57,15 +57,30 @@ private static ImmutableArray GetContainingNamespaceNamesInReverse(IName
return builder.ToImmutable();
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
var name = reader.ReadString();
- var containingSymbolResolution = ResolveContainer(reader);
+
+ var containingSymbolResolution = ResolveContainer(reader, out var containingSymbolFailureReason);
var arity = reader.ReadInteger();
- using var typeArguments = reader.ReadSymbolKeyArray();
+ using var typeArguments = reader.ReadSymbolKeyArray(out var typeArgumentsFailureReason);
+
+ if (containingSymbolFailureReason != null)
+ {
+ failureReason = $"({nameof(ErrorTypeSymbolKey)} {nameof(containingSymbolResolution)} failed -> {containingSymbolFailureReason})";
+ return default;
+ }
+
+ if (typeArgumentsFailureReason != null)
+ {
+ failureReason = $"({nameof(ErrorTypeSymbolKey)} {nameof(typeArguments)} failed -> {typeArgumentsFailureReason})";
+ return default;
+ }
+
if (typeArguments.IsDefault)
{
+ failureReason = $"({nameof(ErrorTypeSymbolKey)} {nameof(typeArguments)} failed)";
return default;
}
@@ -85,15 +100,15 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
reader, container: null, name, arity, typeArgumentsArray));
}
- return CreateResolution(result);
+ return CreateResolution(result, $"({nameof(ErrorTypeSymbolKey)} failed)", out failureReason);
}
- private static SymbolKeyResolution ResolveContainer(SymbolKeyReader reader)
+ private static SymbolKeyResolution ResolveContainer(SymbolKeyReader reader, out string failureReason)
{
var type = reader.ReadInteger();
if (type == 0)
- return reader.ReadSymbolKey();
+ return reader.ReadSymbolKey(out failureReason);
if (type == 1)
{
@@ -104,11 +119,15 @@ private static SymbolKeyResolution ResolveContainer(SymbolKeyReader reader)
for (var i = namespaceNames.Count - 1; i >= 0; i--)
currentNamespace = reader.Compilation.CreateErrorNamespaceSymbol(currentNamespace, namespaceNames[i]);
+ failureReason = null;
return new SymbolKeyResolution(currentNamespace);
}
if (type == 2)
+ {
+ failureReason = null;
return default;
+ }
throw ExceptionUtilities.UnexpectedValue(type);
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.EventSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.EventSymbolKey.cs
index c7c9bbdf8a5e2..efffd875b6a1d 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.EventSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.EventSymbolKey.cs
@@ -14,13 +14,19 @@ public static void Create(IEventSymbol symbol, SymbolKeyWriter visitor)
visitor.WriteSymbolKey(symbol.ContainingType);
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
var metadataName = reader.ReadString();
- var containingTypeResolution = reader.ReadSymbolKey();
+ var containingTypeResolution = reader.ReadSymbolKey(out var containingTypeFailureReason);
+
+ if (containingTypeFailureReason != null)
+ {
+ failureReason = $"({nameof(EventSymbolKey)} {nameof(containingTypeResolution)} failed -> {containingTypeFailureReason})";
+ return default;
+ }
using var result = GetMembersOfNamedType(containingTypeResolution, metadataName);
- return CreateResolution(result);
+ return CreateResolution(result, $"({nameof(EventSymbolKey)} '{metadataName}' not found)", out failureReason);
}
}
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.FieldSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.FieldSymbolKey.cs
index 4e389d647b018..220e987cc90bb 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.FieldSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.FieldSymbolKey.cs
@@ -14,13 +14,19 @@ public static void Create(IFieldSymbol symbol, SymbolKeyWriter visitor)
visitor.WriteSymbolKey(symbol.ContainingType);
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
var metadataName = reader.ReadString();
- var containingTypeResolution = reader.ReadSymbolKey();
+ var containingTypeResolution = reader.ReadSymbolKey(out var containingTypeFailureReason);
+
+ if (containingTypeFailureReason != null)
+ {
+ failureReason = $"({nameof(FieldSymbolKey)} {nameof(containingTypeResolution)} failed -> {containingTypeFailureReason})";
+ return default;
+ }
using var result = GetMembersOfNamedType(containingTypeResolution, metadataName);
- return CreateResolution(result);
+ return CreateResolution(result, $"({nameof(FieldSymbolKey)} '{metadataName}' not found)", out failureReason);
}
}
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.FunctionPointerTypeSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.FunctionPointerTypeSymbolKey.cs
index 31e9b64f12fc3..68d5eaa611535 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.FunctionPointerTypeSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.FunctionPointerTypeSymbolKey.cs
@@ -16,20 +16,40 @@ public static void Create(IFunctionPointerTypeSymbol symbol, SymbolKeyWriter vis
visitor.WriteParameterTypesArray(symbol.Signature.Parameters);
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
var returnRefKind = reader.ReadRefKind();
- var returnType = reader.ReadSymbolKey();
+ var returnType = reader.ReadSymbolKey(out var returnTypeFailureReason);
using var paramRefKinds = reader.ReadRefKindArray();
- using var paramTypes = reader.ReadSymbolKeyArray();
+ using var parameterTypes = reader.ReadSymbolKeyArray(out var parameterTypesFailureReason);
- if (paramTypes.IsDefault || !(returnType.GetAnySymbol() is ITypeSymbol returnTypeSymbol))
+ if (returnTypeFailureReason != null)
{
+ failureReason = $"({nameof(FunctionPointerTypeSymbolKey)} {nameof(returnType)} failed -> {returnTypeFailureReason})";
return default;
}
+ if (parameterTypesFailureReason != null)
+ {
+ failureReason = $"({nameof(FunctionPointerTypeSymbolKey)} {nameof(parameterTypes)} failed -> {parameterTypesFailureReason})";
+ return default;
+ }
+
+ if (parameterTypes.IsDefault)
+ {
+ failureReason = $"({nameof(FunctionPointerTypeSymbolKey)} no parameter types)";
+ return default;
+ }
+
+ if (!(returnType.GetAnySymbol() is ITypeSymbol returnTypeSymbol))
+ {
+ failureReason = $"({nameof(FunctionPointerTypeSymbolKey)} no return type)";
+ return default;
+ }
+
+ failureReason = null;
return new SymbolKeyResolution(reader.Compilation.CreateFunctionPointerTypeSymbol(
- returnTypeSymbol, returnRefKind, paramTypes.ToImmutable(), paramRefKinds.ToImmutable()));
+ returnTypeSymbol, returnRefKind, parameterTypes.ToImmutable(), paramRefKinds.ToImmutable()));
}
}
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.MethodSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.MethodSymbolKey.cs
index a8d1fc0906bc6..27446a85cea4c 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.MethodSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.MethodSymbolKey.cs
@@ -18,10 +18,21 @@ public static void Create(IMethodSymbol symbol, SymbolKeyWriter visitor)
visitor.WriteSymbolKey(symbol.ReceiverType);
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
- var reducedFromResolution = reader.ReadSymbolKey();
- var receiverTypeResolution = reader.ReadSymbolKey();
+ var reducedFromResolution = reader.ReadSymbolKey(out var reducedFromFailureReason);
+ if (reducedFromFailureReason != null)
+ {
+ failureReason = $"({nameof(ReducedExtensionMethodSymbolKey)} {nameof(reducedFromResolution)} failed -> {reducedFromFailureReason})";
+ return default;
+ }
+
+ var receiverTypeResolution = reader.ReadSymbolKey(out var receiverTypeFailureReason);
+ if (receiverTypeFailureReason != null)
+ {
+ failureReason = $"({nameof(ReducedExtensionMethodSymbolKey)} {nameof(receiverTypeResolution)} failed -> {receiverTypeFailureReason})";
+ return default;
+ }
using var result = PooledArrayBuilder.GetInstance();
foreach (var reducedFrom in reducedFromResolution.OfType())
@@ -32,7 +43,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
}
}
- return CreateResolution(result);
+ return CreateResolution(result, $"({nameof(ReducedExtensionMethodSymbolKey)} failed)", out failureReason);
}
}
}
@@ -47,14 +58,25 @@ public static void Create(IMethodSymbol symbol, SymbolKeyWriter visitor)
visitor.WriteSymbolKeyArray(symbol.TypeArguments);
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
- var constructedFrom = reader.ReadSymbolKey();
- using var typeArguments = reader.ReadSymbolKeyArray();
+ var constructedFrom = reader.ReadSymbolKey(out var constructedFromFailureReason);
+ if (constructedFromFailureReason != null)
+ {
+ failureReason = $"({nameof(ConstructedMethodSymbolKey)} {nameof(constructedFrom)} failed -> {constructedFromFailureReason})";
+ return default;
+ }
- if (constructedFrom.SymbolCount == 0 ||
- typeArguments.IsDefault)
+ using var typeArguments = reader.ReadSymbolKeyArray(out var typeArgumentsFailureReason);
+ if (typeArgumentsFailureReason != null)
{
+ failureReason = $"({nameof(ConstructedMethodSymbolKey)} {nameof(typeArguments)} failed -> {typeArgumentsFailureReason})";
+ return default;
+ }
+
+ if (constructedFrom.SymbolCount == 0 || typeArguments.IsDefault)
+ {
+ failureReason = $"({nameof(ConstructedMethodSymbolKey)} {nameof(typeArguments)} failed -> 'constructedFrom.SymbolCount == 0 || typeArguments.IsDefault')";
return default;
}
@@ -69,7 +91,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
}
}
- return CreateResolution(result);
+ return CreateResolution(result, $"({nameof(ConstructedMethodSymbolKey)} could not successfully construct)", out failureReason);
}
}
}
@@ -110,10 +132,11 @@ public static void Create(IMethodSymbol symbol, SymbolKeyWriter visitor)
visitor.PopMethod(symbol);
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
var metadataName = reader.ReadString();
- var containingType = reader.ReadSymbolKey();
+
+ var containingType = reader.ReadSymbolKey(out var containingTypeFailureReason);
var arity = reader.ReadInteger();
var isPartialMethodImplementationPart = reader.ReadBoolean();
using var parameterRefKinds = reader.ReadRefKindArray();
@@ -158,15 +181,21 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
// read out the values. We don't actually need to use them, but we have
// to effectively read past them in the string.
- using (reader.ReadSymbolKeyArray())
+ using (reader.ReadSymbolKeyArray(out _))
{
- _ = reader.ReadSymbolKey();
+ _ = reader.ReadSymbolKey(out _);
}
reader.PopMethod(methodOpt: null);
}
- return CreateResolution(result);
+ if (containingTypeFailureReason != null)
+ {
+ failureReason = $"({nameof(MethodSymbolKey)} {nameof(containingType)} failed -> {containingTypeFailureReason})";
+ return default;
+ }
+
+ return CreateResolution(result, $"({nameof(MethodSymbolKey)} '{metadataName}' not found)", out failureReason);
}
private static IMethodSymbol Resolve(
@@ -207,8 +236,8 @@ private static IMethodSymbol Resolve(
private static IMethodSymbol Resolve(
SymbolKeyReader reader, bool isPartialMethodImplementationPart, IMethodSymbol method)
{
- using var originalParameterTypes = reader.ReadSymbolKeyArray();
- var returnType = (ITypeSymbol)reader.ReadSymbolKey().GetAnySymbol();
+ using var originalParameterTypes = reader.ReadSymbolKeyArray(out _);
+ var returnType = (ITypeSymbol)reader.ReadSymbolKey(out _).GetAnySymbol();
if (reader.ParameterTypesMatch(method.OriginalDefinition.Parameters, originalParameterTypes))
{
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ModuleSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ModuleSymbolKey.cs
index 74275d638e13e..5bd01ebb70a3f 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ModuleSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ModuleSymbolKey.cs
@@ -11,9 +11,15 @@ private static class ModuleSymbolKey
public static void Create(IModuleSymbol symbol, SymbolKeyWriter visitor)
=> visitor.WriteSymbolKey(symbol.ContainingSymbol);
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
- var containingSymbolResolution = reader.ReadSymbolKey();
+ var containingSymbolResolution = reader.ReadSymbolKey(out var containingSymbolFailureReason);
+
+ if (containingSymbolFailureReason != null)
+ {
+ failureReason = $"({nameof(ModuleSymbolKey)} {nameof(containingSymbolResolution)} failed -> {containingSymbolFailureReason})";
+ return default;
+ }
using var result = PooledArrayBuilder.GetInstance();
foreach (var assembly in containingSymbolResolution.OfType())
@@ -23,7 +29,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
result.AddValuesIfNotNull(assembly.Modules);
}
- return CreateResolution(result);
+ return CreateResolution(result, $"({nameof(ModuleSymbolKey)} failed)", out failureReason);
}
}
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.NamedTypeSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.NamedTypeSymbolKey.cs
index 75cbf7dfdc12c..4b94ebe15abc1 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.NamedTypeSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.NamedTypeSymbolKey.cs
@@ -28,16 +28,29 @@ public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor)
}
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
var metadataName = reader.ReadString();
- var containingSymbolResolution = reader.ReadSymbolKey();
+ var containingSymbolResolution = reader.ReadSymbolKey(out var containingSymbolFailureReason);
var arity = reader.ReadInteger();
var isUnboundGenericType = reader.ReadBoolean();
- using var typeArguments = reader.ReadSymbolKeyArray();
+ using var typeArguments = reader.ReadSymbolKeyArray(out var typeArgumentsFailureReason);
+
+ if (containingSymbolFailureReason != null)
+ {
+ failureReason = $"({nameof(NamedTypeSymbolKey)} {nameof(containingSymbolFailureReason)} failed -> {containingSymbolFailureReason})";
+ return default;
+ }
+
+ if (typeArgumentsFailureReason != null)
+ {
+ failureReason = $"({nameof(NamedTypeSymbolKey)} {nameof(typeArguments)} failed -> {typeArgumentsFailureReason})";
+ return default;
+ }
if (typeArguments.IsDefault)
{
+ failureReason = $"({nameof(NamedTypeSymbolKey)} {nameof(typeArguments)} failed)";
return default;
}
@@ -52,7 +65,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
isUnboundGenericType, typeArgumentArray);
}
- return CreateResolution(result);
+ return CreateResolution(result, $"({nameof(NamedTypeSymbolKey)} failed)", out failureReason);
}
private static void Resolve(
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.NamespaceSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.NamespaceSymbolKey.cs
index 22298b8835924..b3e0fbfc437f2 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.NamespaceSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.NamespaceSymbolKey.cs
@@ -52,14 +52,21 @@ public static void Create(INamespaceSymbol symbol, SymbolKeyWriter visitor)
}
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
var metadataName = reader.ReadString();
var isCompilationGlobalNamespace = reader.ReadBoolean();
- var containingSymbolResolution = reader.ReadSymbolKey();
+ var containingSymbolResolution = reader.ReadSymbolKey(out var containingSymbolFailureReason);
+
+ if (containingSymbolFailureReason != null)
+ {
+ failureReason = $"({nameof(EventSymbolKey)} {nameof(containingSymbolResolution)} failed -> {containingSymbolFailureReason})";
+ return default;
+ }
if (isCompilationGlobalNamespace)
{
+ failureReason = null;
return new SymbolKeyResolution(reader.Compilation.GlobalNamespace);
}
@@ -88,7 +95,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
}
}
- return CreateResolution(result);
+ return CreateResolution(result, $"({nameof(NamespaceSymbolKey)} '{metadataName}' not found)", out failureReason);
}
}
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ParameterSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ParameterSymbolKey.cs
index 58cbb56dc7e04..bca5b85438580 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ParameterSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ParameterSymbolKey.cs
@@ -16,10 +16,16 @@ public static void Create(IParameterSymbol symbol, SymbolKeyWriter visitor)
visitor.WriteSymbolKey(symbol.ContainingSymbol);
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
var metadataName = reader.ReadString();
- var containingSymbolResolution = reader.ReadSymbolKey();
+ var containingSymbolResolution = reader.ReadSymbolKey(out var containingSymbolFailureReason);
+
+ if (containingSymbolFailureReason != null)
+ {
+ failureReason = $"({nameof(ParameterSymbolKey)} {nameof(containingSymbolResolution)} failed -> {containingSymbolFailureReason})";
+ return default;
+ }
using var result = PooledArrayBuilder.GetInstance();
foreach (var container in containingSymbolResolution)
@@ -55,7 +61,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
}
}
- return CreateResolution(result);
+ return CreateResolution(result, $"({nameof(ParameterSymbolKey)} '{metadataName}' not found)", out failureReason);
}
private static void Resolve(
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.PointerTypeSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.PointerTypeSymbolKey.cs
index 28cbc7980e3b3..37a6e0339bce7 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.PointerTypeSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.PointerTypeSymbolKey.cs
@@ -11,9 +11,15 @@ private static class PointerTypeSymbolKey
public static void Create(IPointerTypeSymbol symbol, SymbolKeyWriter visitor)
=> visitor.WriteSymbolKey(symbol.PointedAtType);
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
- var pointedAtTypeResolution = reader.ReadSymbolKey();
+ var pointedAtTypeResolution = reader.ReadSymbolKey(out var pointedAtTypeFailureReason);
+
+ if (pointedAtTypeFailureReason != null)
+ {
+ failureReason = $"({nameof(PointerTypeSymbolKey)} {nameof(pointedAtTypeResolution)} failed -> {pointedAtTypeFailureReason})";
+ return default;
+ }
using var result = PooledArrayBuilder.GetInstance(pointedAtTypeResolution.SymbolCount);
foreach (var typeSymbol in pointedAtTypeResolution.OfType())
@@ -21,7 +27,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
result.AddIfNotNull(reader.Compilation.CreatePointerTypeSymbol(typeSymbol));
}
- return CreateResolution(result);
+ return CreateResolution(result, $"({nameof(PointerTypeSymbolKey)} could not resolve)", out failureReason);
}
}
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.PropertySymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.PropertySymbolKey.cs
index a9e0306209664..757418e0d3f6a 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.PropertySymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.PropertySymbolKey.cs
@@ -17,17 +17,29 @@ public static void Create(IPropertySymbol symbol, SymbolKeyWriter visitor)
visitor.WriteParameterTypesArray(symbol.OriginalDefinition.Parameters);
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
var metadataName = reader.ReadString();
- var containingTypeResolution = reader.ReadSymbolKey();
+ var containingTypeResolution = reader.ReadSymbolKey(out var containingTypeFailureReason);
var isIndexer = reader.ReadBoolean();
-
using var refKinds = reader.ReadRefKindArray();
- using var parameterTypes = reader.ReadSymbolKeyArray();
+ using var parameterTypes = reader.ReadSymbolKeyArray(out var parameterTypesFailureReason);
+
+ if (containingTypeFailureReason != null)
+ {
+ failureReason = $"({nameof(PropertySymbolKey)} {nameof(containingTypeResolution)} failed -> {containingTypeFailureReason})";
+ return default;
+ }
+
+ if (parameterTypesFailureReason != null)
+ {
+ failureReason = $"({nameof(PropertySymbolKey)} {nameof(parameterTypes)} failed -> {parameterTypesFailureReason})";
+ return default;
+ }
if (parameterTypes.IsDefault)
{
+ failureReason = $"({nameof(PropertySymbolKey)} no parameter types)";
return default;
}
@@ -45,7 +57,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
}
}
- return CreateResolution(result);
+ return CreateResolution(result, $"({nameof(PropertySymbolKey)} '{metadataName}' not found)", out failureReason);
}
}
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs
index 8459282621be1..41ebbdf20795f 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs
@@ -25,9 +25,9 @@ private abstract class Reader : IDisposable
protected const char SpaceChar = ' ';
protected const char DoubleQuoteChar = '"';
- private readonly Func _readString;
- private readonly Func _readBoolean;
- private readonly Func _readRefKind;
+ private readonly ReadFunction _readString;
+ private readonly ReadFunction _readBoolean;
+ private readonly ReadFunction _readRefKind;
protected string Data { get; private set; }
public CancellationToken CancellationToken { get; private set; }
@@ -104,14 +104,22 @@ protected char EatSpace()
=> Eat(SpaceChar);
public bool ReadBoolean()
+ => ReadBoolean(out _);
+
+ public bool ReadBoolean(out string failureReason)
{
+ failureReason = null;
var val = ReadInteger();
Debug.Assert(val == 0 || val == 1);
return val == 1;
}
public TStringResult ReadString()
+ => ReadString(out _);
+
+ public TStringResult ReadString(out string failureReason)
{
+ failureReason = null;
EatSpace();
return ReadStringNoSpace();
}
@@ -164,15 +172,15 @@ private void EatDoubleQuote()
=> Eat(DoubleQuoteChar);
public PooledArrayBuilder ReadStringArray()
- => ReadArray(_readString);
+ => ReadArray(_readString, out _);
public PooledArrayBuilder ReadBooleanArray()
- => ReadArray(_readBoolean);
+ => ReadArray(_readBoolean, out _);
public PooledArrayBuilder ReadRefKindArray()
- => ReadArray(_readRefKind);
+ => ReadArray(_readRefKind, out _);
- public PooledArrayBuilder ReadArray(Func readFunction)
+ public PooledArrayBuilder ReadArray(ReadFunction readFunction, out string failureReason)
{
var builder = PooledArrayBuilder.GetInstance();
EatSpace();
@@ -182,19 +190,33 @@ public PooledArrayBuilder ReadArray(Func readFunction)
EatOpenParen();
Eat(SymbolKeyType.Array);
+ string totalFailureReason = null;
var length = ReadInteger();
for (var i = 0; i < length; i++)
{
CancellationToken.ThrowIfCancellationRequested();
- builder.Builder.Add(readFunction());
+ builder.Builder.Add(readFunction(out var elementFailureReason));
+
+ if (elementFailureReason != null)
+ {
+ var reason = $"element {i} failed {elementFailureReason}";
+ totalFailureReason = totalFailureReason == null
+ ? $"({reason})"
+ : $"(totalFailureReason -> {reason})";
+ }
}
EatCloseParen();
+ failureReason = totalFailureReason;
return builder;
}
public RefKind ReadRefKind()
+ => ReadRefKind(out _);
+
+ public RefKind ReadRefKind(out string failureReason)
{
+ failureReason = null;
return (RefKind)ReadInteger();
}
}
@@ -267,13 +289,15 @@ protected override object CreateNullForString()
=> null;
}
+ private delegate T ReadFunction(out string failureReason);
+
private class SymbolKeyReader : Reader
{
private static readonly ObjectPool s_readerPool = SharedPools.Default();
private readonly Dictionary _idToResult = new Dictionary();
- private readonly Func _readSymbolKey;
- private readonly Func _readLocation;
+ private readonly ReadFunction _readSymbolKey;
+ private readonly ReadFunction _readLocation;
public Compilation Compilation { get; private set; }
public bool IgnoreAssemblyKey { get; private set; }
@@ -379,7 +403,7 @@ internal SyntaxTree GetSyntaxTree(string filePath)
#region Symbols
- public SymbolKeyResolution ReadSymbolKey()
+ public SymbolKeyResolution ReadSymbolKey(out string failureReason)
{
CancellationToken.ThrowIfCancellationRequested();
EatSpace();
@@ -388,6 +412,7 @@ public SymbolKeyResolution ReadSymbolKey()
if (type == SymbolKeyType.Null)
{
Eat(type);
+ failureReason = null;
return default;
}
@@ -401,10 +426,11 @@ public SymbolKeyResolution ReadSymbolKey()
{
var id = ReadInteger();
result = _idToResult[id];
+ failureReason = null;
}
else
{
- result = ReadWorker(type);
+ result = ReadWorker(type, out failureReason);
var id = ReadInteger();
_idToResult[id] = result;
}
@@ -414,32 +440,32 @@ public SymbolKeyResolution ReadSymbolKey()
return result;
}
- private SymbolKeyResolution ReadWorker(SymbolKeyType type)
+ private SymbolKeyResolution ReadWorker(SymbolKeyType type, out string failureReason)
=> type switch
{
- SymbolKeyType.Alias => AliasSymbolKey.Resolve(this),
- SymbolKeyType.BodyLevel => BodyLevelSymbolKey.Resolve(this),
- SymbolKeyType.ConstructedMethod => ConstructedMethodSymbolKey.Resolve(this),
- SymbolKeyType.NamedType => NamedTypeSymbolKey.Resolve(this),
- SymbolKeyType.ErrorType => ErrorTypeSymbolKey.Resolve(this),
- SymbolKeyType.Field => FieldSymbolKey.Resolve(this),
- SymbolKeyType.FunctionPointer => FunctionPointerTypeSymbolKey.Resolve(this),
- SymbolKeyType.DynamicType => DynamicTypeSymbolKey.Resolve(this),
- SymbolKeyType.Method => MethodSymbolKey.Resolve(this),
- SymbolKeyType.Namespace => NamespaceSymbolKey.Resolve(this),
- SymbolKeyType.PointerType => PointerTypeSymbolKey.Resolve(this),
- SymbolKeyType.Parameter => ParameterSymbolKey.Resolve(this),
- SymbolKeyType.Property => PropertySymbolKey.Resolve(this),
- SymbolKeyType.ArrayType => ArrayTypeSymbolKey.Resolve(this),
- SymbolKeyType.Assembly => AssemblySymbolKey.Resolve(this),
- SymbolKeyType.TupleType => TupleTypeSymbolKey.Resolve(this),
- SymbolKeyType.Module => ModuleSymbolKey.Resolve(this),
- SymbolKeyType.Event => EventSymbolKey.Resolve(this),
- SymbolKeyType.ReducedExtensionMethod => ReducedExtensionMethodSymbolKey.Resolve(this),
- SymbolKeyType.TypeParameter => TypeParameterSymbolKey.Resolve(this),
- SymbolKeyType.AnonymousType => AnonymousTypeSymbolKey.Resolve(this),
- SymbolKeyType.AnonymousFunctionOrDelegate => AnonymousFunctionOrDelegateSymbolKey.Resolve(this),
- SymbolKeyType.TypeParameterOrdinal => TypeParameterOrdinalSymbolKey.Resolve(this),
+ SymbolKeyType.Alias => AliasSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.BodyLevel => BodyLevelSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.ConstructedMethod => ConstructedMethodSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.NamedType => NamedTypeSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.ErrorType => ErrorTypeSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.Field => FieldSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.FunctionPointer => FunctionPointerTypeSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.DynamicType => DynamicTypeSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.Method => MethodSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.Namespace => NamespaceSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.PointerType => PointerTypeSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.Parameter => ParameterSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.Property => PropertySymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.ArrayType => ArrayTypeSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.Assembly => AssemblySymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.TupleType => TupleTypeSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.Module => ModuleSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.Event => EventSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.ReducedExtensionMethod => ReducedExtensionMethodSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.TypeParameter => TypeParameterSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.AnonymousType => AnonymousTypeSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.AnonymousFunctionOrDelegate => AnonymousFunctionOrDelegateSymbolKey.Resolve(this, out failureReason),
+ SymbolKeyType.TypeParameterOrdinal => TypeParameterOrdinalSymbolKey.Resolve(this, out failureReason),
_ => throw new NotImplementedException(),
};
@@ -453,9 +479,14 @@ private SymbolKeyResolution ReadWorker(SymbolKeyType type)
/// Callers should the instance returned. No check is
/// necessary if default was returned before calling
///
- public PooledArrayBuilder ReadSymbolKeyArray() where TSymbol : ISymbol
+ public PooledArrayBuilder ReadSymbolKeyArray(out string failureReason) where TSymbol : ISymbol
{
- using var resolutions = ReadArray(_readSymbolKey);
+ using var resolutions = ReadArray(_readSymbolKey, out var elementsFailureReason);
+ if (elementsFailureReason != null)
+ {
+ failureReason = elementsFailureReason;
+ return default;
+ }
var result = PooledArrayBuilder.GetInstance();
foreach (var resolution in resolutions)
@@ -467,10 +498,12 @@ public PooledArrayBuilder ReadSymbolKeyArray() where TSymbol :
else
{
result.Dispose();
+ failureReason = $"({nameof(ReadSymbolKeyArray)} incorrect type for element)";
return default;
}
}
+ failureReason = null;
return result;
}
@@ -494,12 +527,13 @@ protected override string CreateNullForString()
#region Locations
- public Location ReadLocation()
+ public Location ReadLocation(out string failureReason)
{
EatSpace();
if ((SymbolKeyType)Data[Position] == SymbolKeyType.Null)
{
Eat(SymbolKeyType.Null);
+ failureReason = null;
return null;
}
@@ -515,14 +549,21 @@ public Location ReadLocation()
var syntaxTree = GetSyntaxTree(filePath);
if (syntaxTree != null)
{
+ failureReason = null;
return Location.Create(syntaxTree, new TextSpan(start, length));
}
}
else if (kind == LocationKind.MetadataFile)
{
- var assemblyResolution = ReadSymbolKey();
+ var assemblyResolution = ReadSymbolKey(out var assemblyFailureReason);
var moduleName = ReadString();
+ if (assemblyFailureReason != null)
+ {
+ failureReason = $"{nameof(ReadLocation)} {nameof(assemblyResolution)} failed -> " + assemblyFailureReason;
+ return Location.None;
+ }
+
// We may be resolving in a compilation where we don't have a module
// with this name. In that case, just map this location to none.
if (assemblyResolution.GetAnySymbol() is IAssemblySymbol assembly)
@@ -533,12 +574,14 @@ public Location ReadLocation()
var location = FirstOrDefault(module.Locations);
if (location != null)
{
+ failureReason = null;
return location;
}
}
}
}
+ failureReason = null;
return Location.None;
}
@@ -576,8 +619,8 @@ private static IModuleSymbol GetModule(IEnumerable modules, strin
return null;
}
- public PooledArrayBuilder ReadLocationArray()
- => ReadArray(_readLocation);
+ public PooledArrayBuilder ReadLocationArray(out string failureReason)
+ => ReadArray(_readLocation, out failureReason);
#endregion
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.TupleTypeSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.TupleTypeSymbolKey.cs
index cb2557af71a76..66089b79ec865 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.TupleTypeSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.TupleTypeSymbolKey.cs
@@ -17,11 +17,20 @@ public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor)
{
Debug.Assert(symbol.IsTupleType);
+ var isError = symbol.TupleUnderlyingType.TypeKind == TypeKind.Error;
+
var friendlyNames = ArrayBuilder.GetInstance();
var locations = ArrayBuilder.GetInstance();
- var isError = symbol.TupleUnderlyingType.TypeKind == TypeKind.Error;
+ foreach (var element in symbol.TupleElements)
+ {
+ friendlyNames.Add(element.IsImplicitlyDeclared ? null : element.Name);
+ locations.Add(FirstOrDefault(element.Locations) ?? Location.None);
+ }
+
visitor.WriteBoolean(isError);
+ visitor.WriteStringArray(friendlyNames.ToImmutableAndFree());
+ visitor.WriteLocationArray(locations.ToImmutableAndFree());
if (isError)
{
@@ -38,76 +47,79 @@ public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor)
{
visitor.WriteSymbolKey(symbol.TupleUnderlyingType);
}
+ }
- foreach (var element in symbol.TupleElements)
- {
- friendlyNames.Add(element.IsImplicitlyDeclared ? null : element.Name);
- locations.Add(FirstOrDefault(element.Locations) ?? Location.None);
- }
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
+ {
+ var isError = reader.ReadBoolean();
- visitor.WriteStringArray(friendlyNames.ToImmutableAndFree());
- visitor.WriteLocationArray(locations.ToImmutableAndFree());
+ return isError ? ResolveErrorTuple(reader, out failureReason) : ResolveNormalTuple(reader, out failureReason);
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ private static SymbolKeyResolution ResolveNormalTuple(SymbolKeyReader reader, out string failureReason)
{
- var isError = reader.ReadBoolean();
- if (isError)
- {
- using var elementTypes = reader.ReadSymbolKeyArray();
- using var elementNames = reader.ReadStringArray();
- var elementLocations = ReadElementLocations(reader);
+ using var elementNames = reader.ReadStringArray();
+ var elementLocations = ReadElementLocations(reader, out var elementLocationsFailureReason);
+ var underlyingTypeResolution = reader.ReadSymbolKey(out var underlyingTypeFailureReason);
- if (!elementTypes.IsDefault)
- {
- try
- {
- var result = reader.Compilation.CreateTupleTypeSymbol(
- elementTypes.ToImmutable(), elementNames.ToImmutable(), elementLocations);
- return new SymbolKeyResolution(result);
- }
- catch (ArgumentException)
- {
- }
- }
+ if (underlyingTypeFailureReason != null)
+ {
+ failureReason = $"({nameof(TupleTypeSymbolKey)} {nameof(underlyingTypeResolution)} failed -> {underlyingTypeFailureReason})";
+ return default;
}
- else
+
+ using var result = PooledArrayBuilder.GetInstance();
+
+ var elementNamesArray = elementNames.ToImmutable();
+ foreach (var namedType in underlyingTypeResolution.OfType())
{
- var underlyingTypeResolution = reader.ReadSymbolKey();
- using var elementNamesBuilder = reader.ReadStringArray();
- var elementLocations = ReadElementLocations(reader);
+ result.AddIfNotNull(reader.Compilation.CreateTupleTypeSymbol(
+ namedType, elementNamesArray, elementLocations));
+ }
- try
- {
- using var result = PooledArrayBuilder.GetInstance();
+ return CreateResolution(result, $"({nameof(TupleTypeSymbolKey)} failed)", out failureReason);
+ }
- var elementNames = elementNamesBuilder.ToImmutable();
- foreach (var namedType in underlyingTypeResolution.OfType())
- {
- result.AddIfNotNull(reader.Compilation.CreateTupleTypeSymbol(
- namedType, elementNames, elementLocations));
- }
+ private static SymbolKeyResolution ResolveErrorTuple(SymbolKeyReader reader, out string failureReason)
+ {
+ using var elementNames = reader.ReadStringArray();
+ var elementLocations = ReadElementLocations(reader, out var elementLocationsFailureReason);
+ using var elementTypes = reader.ReadSymbolKeyArray(out var elementTypesFailureReason);
- return CreateResolution(result);
- }
- catch (ArgumentException)
- {
- }
+ if (elementLocationsFailureReason != null)
+ {
+ failureReason = $"({nameof(TupleTypeSymbolKey)} {nameof(elementLocations)} failed -> {elementLocationsFailureReason})";
+ return default;
+ }
+
+ if (elementTypesFailureReason != null)
+ {
+ failureReason = $"({nameof(TupleTypeSymbolKey)} {nameof(elementTypes)} failed -> {elementTypesFailureReason})";
+ return default;
+ }
+
+ if (elementTypes.IsDefault)
+ {
+ failureReason = $"({nameof(TupleTypeSymbolKey)} {nameof(elementTypes)} failed)";
+ return default;
}
- return new SymbolKeyResolution(reader.Compilation.ObjectType);
+ var result = reader.Compilation.CreateTupleTypeSymbol(
+ elementTypes.ToImmutable(), elementNames.ToImmutable(), elementLocations);
+ failureReason = null;
+ return new SymbolKeyResolution(result);
}
- private static ImmutableArray ReadElementLocations(SymbolKeyReader reader)
+ private static ImmutableArray ReadElementLocations(SymbolKeyReader reader, out string failureReason)
{
- using var elementLocations = reader.ReadLocationArray();
+ using var elementLocations = reader.ReadLocationArray(out failureReason);
+ if (failureReason != null)
+ return default;
// Compiler API requires that all the locations are non-null, or that there is a default
// immutable array passed in.
if (elementLocations.Builder.All(loc => loc == null))
- {
return default;
- }
return elementLocations.ToImmutable();
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.TypeParameterOrdinalSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.TypeParameterOrdinalSymbolKey.cs
index cd422fb78d0c6..f1d5c470ec03c 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.TypeParameterOrdinalSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.TypeParameterOrdinalSymbolKey.cs
@@ -17,15 +17,21 @@ public static void Create(ITypeParameterSymbol symbol, int methodIndex, SymbolKe
visitor.WriteInteger(symbol.Ordinal);
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
var methodIndex = reader.ReadInteger();
var ordinal = reader.ReadInteger();
var method = reader.ResolveMethod(methodIndex);
+
var typeParameter = method?.TypeParameters[ordinal];
- return typeParameter == null
- ? default
- : new SymbolKeyResolution(typeParameter);
+ if (typeParameter == null)
+ {
+ failureReason = $"({nameof(TypeParameterOrdinalSymbolKey)} failed)";
+ return default;
+ }
+
+ failureReason = null;
+ return new SymbolKeyResolution(typeParameter);
}
}
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.TypeParameterSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.TypeParameterSymbolKey.cs
index ef2cf73383080..fcafa1134af87 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.TypeParameterSymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.TypeParameterSymbolKey.cs
@@ -25,20 +25,34 @@ public static void Create(ITypeParameterSymbol symbol, SymbolKeyWriter visitor)
}
}
- public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
{
var isCref = reader.ReadBoolean();
if (isCref)
{
- var location = reader.ReadLocation();
+ var location = reader.ReadLocation(out var locationFailureReason);
+ if (locationFailureReason != null)
+ {
+ failureReason = $"({nameof(TypeParameterSymbolKey)} {nameof(location)} failed -> {locationFailureReason})";
+ return default;
+ }
+
var resolution = reader.ResolveLocation(location);
+
+ failureReason = null;
return resolution.GetValueOrDefault();
}
else
{
var metadataName = reader.ReadString();
- var containingSymbolResolution = reader.ReadSymbolKey();
+ var containingSymbolResolution = reader.ReadSymbolKey(out var containingSymbolFailureReason);
+
+ if (containingSymbolFailureReason != null)
+ {
+ failureReason = $"({nameof(TypeParameterSymbolKey)} {nameof(containingSymbolResolution)} failed -> {containingSymbolFailureReason})";
+ return default;
+ }
using var result = PooledArrayBuilder.GetInstance();
foreach (var containingSymbol in containingSymbolResolution)
@@ -52,7 +66,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
}
}
- return CreateResolution(result);
+ return CreateResolution(result, $"({nameof(TypeParameterSymbolKey)} '{metadataName}' not found)", out failureReason);
}
}
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.cs
index b558e880cc728..af4bca827b1ba 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.cs
@@ -160,16 +160,31 @@ public static bool CanCreate(ISymbol symbol, CancellationToken cancellationToken
public static SymbolKeyResolution ResolveString(
string symbolKey, Compilation compilation,
bool ignoreAssemblyKey = false, CancellationToken cancellationToken = default)
+ {
+ return ResolveString(symbolKey, compilation, ignoreAssemblyKey, out _, cancellationToken);
+ }
+
+ public static SymbolKeyResolution ResolveString(
+ string symbolKey, Compilation compilation,
+ out string failureReason, CancellationToken cancellationToken)
+ {
+ return ResolveString(symbolKey, compilation, ignoreAssemblyKey: false, out failureReason, cancellationToken);
+ }
+
+ public static SymbolKeyResolution ResolveString(
+ string symbolKey, Compilation compilation, bool ignoreAssemblyKey,
+ out string failureReason, CancellationToken cancellationToken)
{
using var reader = SymbolKeyReader.GetReader(
symbolKey, compilation, ignoreAssemblyKey, cancellationToken);
var version = reader.ReadFormatVersion();
if (version != FormatVersion)
{
+ failureReason = $"({nameof(SymbolKey)} invalid format '${version}')";
return default;
}
- var result = reader.ReadSymbolKey();
+ var result = reader.ReadSymbolKey(out failureReason);
Debug.Assert(reader.Position == symbolKey.Length);
return result;
}
@@ -208,7 +223,8 @@ public SymbolKeyResolution Resolve(
public override string ToString()
=> _symbolKeyData;
- private static SymbolKeyResolution CreateResolution(PooledArrayBuilder symbols)
+ private static SymbolKeyResolution CreateResolution(
+ PooledArrayBuilder symbols, string reasonIfFailed, out string failureReason)
where TSymbol : class, ISymbol
{
#if DEBUG
@@ -220,14 +236,17 @@ private static SymbolKeyResolution CreateResolution(PooledArrayBuilder<
if (symbols.Builder.Count == 0)
{
+ failureReason = reasonIfFailed;
return default;
}
else if (symbols.Builder.Count == 1)
{
+ failureReason = null;
return new SymbolKeyResolution(symbols.Builder[0]);
}
else
{
+ failureReason = null;
return new SymbolKeyResolution(
ImmutableArray.CastUp(symbols.Builder.ToImmutable()),
CandidateReason.Ambiguous);