diff --git a/build/all_projects.settings.targets b/build/all_projects.settings.targets
index 872e74d5d..2adfaf275 100755
--- a/build/all_projects.settings.targets
+++ b/build/all_projects.settings.targets
@@ -21,6 +21,8 @@
$(MIEngineRoot)\tools$(MIEngineRoot)obj\$(Configuration)\$(MSBuildProjectName)\$(ToolsHome)\NuGet\NuGet.exe
+
+ 12.0
diff --git a/src/DebugEngineHost.Common/HostLogChannel.cs b/src/DebugEngineHost.Common/HostLogChannel.cs
index 14bdc1b57..699cdb3ad 100644
--- a/src/DebugEngineHost.Common/HostLogChannel.cs
+++ b/src/DebugEngineHost.Common/HostLogChannel.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft. All rights reserved.
+// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
/*
@@ -51,18 +51,18 @@ public interface ILogChannel
public class HostLogChannel : ILogChannel
{
private readonly Action _log;
- private StreamWriter _logFile;
+ private StreamWriter? _logFile;
private LogLevel _minLevelToBeLogged;
private readonly object _lock = new object();
- private HostLogChannel() { }
+ private HostLogChannel() { _log = null!; }
- public HostLogChannel(Action logAction, string file, LogLevel logLevel)
+ public HostLogChannel(Action logAction, string? file, LogLevel logLevel)
{
_log = logAction;
- if (!string.IsNullOrEmpty(file))
+ if (!IsNullOrEmpty(file))
{
_logFile = File.CreateText(file);
}
diff --git a/src/DebugEngineHost.Stub/DebugEngineHost.Stub.csproj b/src/DebugEngineHost.Stub/DebugEngineHost.Stub.csproj
index d84411a11..197d85e9d 100755
--- a/src/DebugEngineHost.Stub/DebugEngineHost.Stub.csproj
+++ b/src/DebugEngineHost.Stub/DebugEngineHost.Stub.csproj
@@ -3,6 +3,7 @@
1.0.0
+ enable
@@ -23,6 +24,12 @@
+
+
+ Shared\%(Filename).cs
+
+
+
diff --git a/src/DebugEngineHost.Stub/DebugEngineHost.ref.cs b/src/DebugEngineHost.Stub/DebugEngineHost.ref.cs
index 3d4462044..7b7fae658 100644
--- a/src/DebugEngineHost.Stub/DebugEngineHost.ref.cs
+++ b/src/DebugEngineHost.Stub/DebugEngineHost.ref.cs
@@ -1,10 +1,10 @@
-// Copyright (c) Microsoft. All rights reserved.
+// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.VisualStudio.Debugger.Interop;
using System;
using System.Collections.Generic;
-using System.Diagnostics;
+using ConditionalAttribute = global::System.Diagnostics.ConditionalAttribute;
using System.Threading;
@@ -88,7 +88,7 @@ public void Dispose() { }
/// Name of the value to obtain
/// [Optional] null if the value doesn't exist, otherwise the value
///
- public object GetValue(string valueName)
+ public object? GetValue(string valueName)
{
throw new NotImplementedException();
}
@@ -146,7 +146,7 @@ public string RegistryRoot
///
/// The metric to read.
/// [Optional] value of the metric. Null if the metric is not defined.
- public object GetEngineMetric(string metric)
+ public object? GetEngineMetric(string metric)
{
throw new NotImplementedException();
}
@@ -178,7 +178,7 @@ public T GetDebuggerConfigurationSetting(string settingName, T defaultValue)
///
/// launch options type name
///
- public object GetCustomLauncher(string launcherTypeName)
+ public object? GetCustomLauncher(string launcherTypeName)
{
throw new NotImplementedException();
}
@@ -277,8 +277,8 @@ public static void EnableNatvisDiagnostics(Action callback, LogLevel lev
///
/// Sets the log file to write to.
///
- /// The file to write engine logs to.
- public static void SetEngineLogFile(string logFile)
+ /// The file to write engine logs to, or null if none
+ public static void SetEngineLogFile(string? logFile)
{
throw new NotImplementedException();
}
@@ -287,7 +287,7 @@ public static void SetEngineLogFile(string logFile)
/// Gets the engine log channel created by 'EnableHostLogging'
///
/// A logger object if logging is enabled, or null if it is not
- public static ILogChannel GetEngineLogChannel()
+ public static ILogChannel? GetEngineLogChannel()
{
throw new NotImplementedException();
}
@@ -296,7 +296,7 @@ public static ILogChannel GetEngineLogChannel()
/// Gets the Natvis log channel if its been created.
///
/// A logger object if logging is enabled, or null if it is not
- public static ILogChannel GetNatvisLogChannel()
+ public static ILogChannel? GetNatvisLogChannel()
{
throw new NotImplementedException();
}
@@ -339,7 +339,7 @@ public static class HostLoader
/// CLSID to CoCreate
/// [Optional] loaded object. Null if the type is not registered, or points to a type that doesn't exist
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Co")]
- public static object VsCoCreateManagedObject(HostConfigurationStore configStore, Guid clsid)
+ public static object? VsCoCreateManagedObject(HostConfigurationStore configStore, Guid clsid)
{
throw new NotImplementedException();
}
@@ -472,7 +472,7 @@ public static void FindNatvis(NatvisLoader loader)
///
/// Enable's tracking the VS 'Natvis Diagnostic Messages (C++ only)' setting.
///
- public static IDisposable WatchNatvisOptionSetting(HostConfigurationStore configStore, ILogChannel natvisLogger)
+ public static IDisposable? WatchNatvisOptionSetting(HostConfigurationStore configStore, ILogChannel natvisLogger)
{
throw new NotImplementedException();
}
@@ -480,7 +480,7 @@ public static IDisposable WatchNatvisOptionSetting(HostConfigurationStore config
///
/// Return the solution's root directory, null if no solution
///
- public static string FindSolutionRoot()
+ public static string? FindSolutionRoot()
{
throw new NotImplementedException();
}
@@ -663,7 +663,7 @@ public static void SendEvent(string eventName, params KeyValuePair
/// Exception object to report.
/// Name of the engine reporting the exception. Ex:Microsoft.MIEngine
- public static void ReportCurrentException(Exception currentException, string engineName)
+ public static void ReportCurrentException(Exception currentException, string? engineName)
{
throw new NotImplementedException();
}
diff --git a/src/DebugEngineHost.Stub/Shared/NullableHelpers.cs b/src/DebugEngineHost.Stub/Shared/NullableHelpers.cs
new file mode 100644
index 000000000..9dc195616
--- /dev/null
+++ b/src/DebugEngineHost.Stub/Shared/NullableHelpers.cs
@@ -0,0 +1,151 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+global using static global::Microsoft.DebugEngineHost.NullableHelpers;
+
+namespace Microsoft.DebugEngineHost
+{
+ using System.Diagnostics.CodeAnalysis;
+ using ConditionalAttribute = System.Diagnostics.ConditionalAttribute;
+ using SysDebug = System.Diagnostics.Debug;
+
+#pragma warning disable 8763 // A method marked [DoesNotReturn] should not return.
+
+ ///
+ /// Helper class to support nullable reference work when compiling against .NET Standard / .NET Framework
+ ///
+ public static class NullableHelpers
+ {
+ ///
+ /// Wrapper around string.IsNullOrEmpty to add the `[NotNullWhen(false)]` annotation
+ ///
+ /// string to test
+ /// True if the string is null or empty
+ static public bool IsNullOrEmpty([NotNullWhen(false)] string? s)
+ {
+ return string.IsNullOrEmpty(s);
+ }
+
+ ///
+ /// Wrapper around string.IsNullOrWhiteSpace to add the `[NotNullWhen(false)]` annotation
+ ///
+ /// string to test
+ /// True if the string is null, empty, or only whitespace
+ static public bool IsNullOrWhiteSpace([NotNullWhen(false)] string? s)
+ {
+ return string.IsNullOrWhiteSpace(s);
+ }
+
+ ///
+ /// This is a shim on top of the class which adds attributes used
+ /// in nullability analysis. This is important because without the DoesNotReturnIf/DoesNotReturn attributes,
+ /// on Debug.Assert/Debug.Fail the C# compiler will see code like:
+ ///
+ /// Debug.Assert(myArg != null, "Invalid argument")
+ ///
+ /// And decide that because the code was attempting to handle 'myArg' being null, that it must be possible
+ /// for it to be null.
+ ///
+ [System.Diagnostics.DebuggerNonUserCode()]
+ public static class Debug
+ {
+ ///
+ /// Checks for a condition; if the condition is false, displays a message box that shows the call stack.
+ ///
+ /// The conditional expression to evaluate. If the condition is true, a failure message is not sent and the message box is not displayed.
+ [Conditional("DEBUG")]
+ public static void Assert([DoesNotReturnIf(false)] bool condition)
+ {
+ SysDebug.Assert(condition);
+ }
+
+ ///
+ /// Checks for a condition; if the condition is false, outputs a specified message and displays a message box that shows the call stack.
+ ///
+ /// The conditional expression to evaluate. If the condition is true, the specified message is not sent and the message box is not displayed.
+ /// The message to send to the collection.
+ [Conditional("DEBUG")]
+ public static void Assert([DoesNotReturnIf(false)] bool condition, string message)
+ {
+ SysDebug.Assert(condition, message);
+ }
+
+ ///
+ /// Checks for a condition; if the condition is false, outputs two specified messages and displays a message box that shows the call stack.
+ ///
+ /// The conditional expression to evaluate. If the condition is true, the specified messages are not sent and the message box is not displayed.
+ /// The message to send to the collection.
+ /// The detailed message to send to the collection.
+ [Conditional("DEBUG")]
+ public static void Assert([DoesNotReturnIf(false)] bool condition, string message, string detailMessage)
+ {
+ SysDebug.Assert(condition, message, detailMessage);
+ }
+
+ ///
+ /// Emits the specified error message.
+ ///
+ /// A message to emit.
+ [Conditional("DEBUG")]
+ [DoesNotReturn]
+ public static void Fail(string message)
+ {
+ SysDebug.Fail(message);
+ }
+
+ ///
+ /// Emits an error message and a detailed error message.
+ ///
+ /// A message to emit.
+ /// A detailed message to emit.
+ [Conditional("DEBUG")]
+ [DoesNotReturn]
+ public static void Fail(string message, string detailMessage)
+ {
+ SysDebug.Fail(message, detailMessage);
+ }
+
+ ///
+ /// Writes a message followed by a line terminator to the debugger.
+ ///
+ /// A message to write.
+ [Conditional("DEBUG")]
+ public static void WriteLine(string message)
+ {
+ SysDebug.WriteLine(message);
+ }
+
+ ///
+ /// Writes the value of the object's method to the debugger.
+ ///
+ /// An object whose value is sent to the debugger.
+ [Conditional("DEBUG")]
+ public static void WriteLine(object value)
+ {
+ SysDebug.WriteLine(value);
+ }
+
+ ///
+ /// Writes a category name and message to the debugger.
+ ///
+ /// A message to write.
+ /// A category name used to organize the output.
+ [Conditional("DEBUG")]
+ public static void WriteLine(string message, string category)
+ {
+ SysDebug.WriteLine(message, category);
+ }
+
+ ///
+ /// Writes a category name and the value of the object's method to the debugger.
+ ///
+ /// An object whose value is sent to the debugger.
+ /// A category name used to organize the output.
+ [Conditional("DEBUG")]
+ public static void WriteLine(object value, string category)
+ {
+ SysDebug.WriteLine(value, category);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/DebugEngineHost.VSCode/DebugEngineHost.VSCode.csproj b/src/DebugEngineHost.VSCode/DebugEngineHost.VSCode.csproj
index 428c8b4ca..58c85fc60 100644
--- a/src/DebugEngineHost.VSCode/DebugEngineHost.VSCode.csproj
+++ b/src/DebugEngineHost.VSCode/DebugEngineHost.VSCode.csproj
@@ -3,6 +3,7 @@
1.0.0
+ enable
@@ -20,11 +21,16 @@
netstandard2.0
-
-
-
-
-
+
+
+ Shared\%(Filename).cs
+
+
+ Shared\%(Filename).cs
+
+
+ Shared\%(Filename).cs
+
diff --git a/src/DebugEngineHost.VSCode/HostConfigurationSection.cs b/src/DebugEngineHost.VSCode/HostConfigurationSection.cs
index 632257540..5fe40a546 100644
--- a/src/DebugEngineHost.VSCode/HostConfigurationSection.cs
+++ b/src/DebugEngineHost.VSCode/HostConfigurationSection.cs
@@ -21,7 +21,7 @@ public void Dispose()
GC.SuppressFinalize(this);
}
- public object GetValue(string valueName)
+ public object? GetValue(string valueName)
{
ExceptionSettings.TriggerState state;
if (_defaultTriggers.TryGetValue(valueName, out state))
diff --git a/src/DebugEngineHost.VSCode/HostConfigurationStore.cs b/src/DebugEngineHost.VSCode/HostConfigurationStore.cs
index 9736c3735..2f391b70d 100644
--- a/src/DebugEngineHost.VSCode/HostConfigurationStore.cs
+++ b/src/DebugEngineHost.VSCode/HostConfigurationStore.cs
@@ -15,11 +15,12 @@ public sealed class HostConfigurationStore
public HostConfigurationStore(string adapterId)
{
- _config = EngineConfiguration.TryGet(adapterId);
- if (_config == null)
+ EngineConfiguration? config = EngineConfiguration.TryGet(adapterId);
+ if (config is null)
{
throw new ArgumentOutOfRangeException(nameof(adapterId));
}
+ _config = config;
}
public void SetEngineGuid(Guid value)
@@ -35,12 +36,12 @@ public string RegistryRoot
}
}
- public object GetCustomLauncher(string launcherTypeName)
+ public object? GetCustomLauncher(string launcherTypeName)
{
throw new NotImplementedException();
}
- public object GetEngineMetric(string metric)
+ public object? GetEngineMetric(string metric)
{
if (string.CompareOrdinal("GlobalVisualizersDirectory", metric) == 0)
{
@@ -55,7 +56,7 @@ public object GetEngineMetric(string metric)
public void GetExceptionCategorySettings(Guid categoryId, out HostConfigurationSection categoryConfigSection, out string categoryName)
{
var category = _config.ExceptionSettings.Categories.FirstOrDefault((x) => x.Id == categoryId);
- if (category == null)
+ if (category is null)
{
throw new InvalidDataException(string.Format(CultureInfo.CurrentCulture, HostResources.Error_ExceptionCategoryMissing, categoryId));
}
diff --git a/src/DebugEngineHost.VSCode/HostLoader.cs b/src/DebugEngineHost.VSCode/HostLoader.cs
index 59d9d9f27..b3727e92b 100644
--- a/src/DebugEngineHost.VSCode/HostLoader.cs
+++ b/src/DebugEngineHost.VSCode/HostLoader.cs
@@ -7,7 +7,7 @@ namespace Microsoft.DebugEngineHost
{
public static class HostLoader
{
- public static object VsCoCreateManagedObject(HostConfigurationStore configStore, Guid clsid)
+ public static object? VsCoCreateManagedObject(HostConfigurationStore configStore, Guid clsid)
{
throw new NotImplementedException();
}
diff --git a/src/DebugEngineHost.VSCode/HostLogger.cs b/src/DebugEngineHost.VSCode/HostLogger.cs
index 1bd6805ab..9d784538e 100644
--- a/src/DebugEngineHost.VSCode/HostLogger.cs
+++ b/src/DebugEngineHost.VSCode/HostLogger.cs
@@ -7,14 +7,14 @@ namespace Microsoft.DebugEngineHost
{
public static class HostLogger
{
- private static ILogChannel s_natvisLogChannel;
- private static ILogChannel s_engineLogChannel;
+ private static ILogChannel? s_natvisLogChannel;
+ private static ILogChannel? s_engineLogChannel;
- private static string s_engineLogFile;
+ private static string? s_engineLogFile;
public static void EnableNatvisDiagnostics(Action callback, LogLevel level = LogLevel.Verbose)
{
- if (s_natvisLogChannel == null)
+ if (s_natvisLogChannel is null)
{
// TODO: Support writing natvis logs to a file.
s_natvisLogChannel = new HostLogChannel(callback, null, level);
@@ -23,23 +23,23 @@ public static void EnableNatvisDiagnostics(Action callback, LogLevel lev
public static void EnableHostLogging(Action callback, LogLevel level = LogLevel.Verbose)
{
- if (s_engineLogChannel == null)
+ if (s_engineLogChannel is null)
{
s_engineLogChannel = new HostLogChannel(callback, s_engineLogFile, level);
}
}
- public static void SetEngineLogFile(string logFile)
+ public static void SetEngineLogFile(string? logFile)
{
s_engineLogFile = logFile;
}
- public static ILogChannel GetEngineLogChannel()
+ public static ILogChannel? GetEngineLogChannel()
{
return s_engineLogChannel;
}
- public static ILogChannel GetNatvisLogChannel()
+ public static ILogChannel? GetNatvisLogChannel()
{
return s_natvisLogChannel;
}
diff --git a/src/DebugEngineHost.VSCode/HostMarshal.cs b/src/DebugEngineHost.VSCode/HostMarshal.cs
index 41f780164..f135307d0 100644
--- a/src/DebugEngineHost.VSCode/HostMarshal.cs
+++ b/src/DebugEngineHost.VSCode/HostMarshal.cs
@@ -80,8 +80,7 @@ public static IDebugDocumentPosition2 GetDocumentPositionForIntPtr(IntPtr docume
{
lock (s_documentPositions)
{
- IDebugDocumentPosition2 documentPosition;
- if (!s_documentPositions.TryGet((int)documentPositionId, out documentPosition))
+ if (!s_documentPositions.TryGet((int)documentPositionId, out IDebugDocumentPosition2? documentPosition))
{
throw new ArgumentOutOfRangeException(nameof(documentPositionId));
}
@@ -94,8 +93,7 @@ public static IDebugFunctionPosition2 GetDebugFunctionPositionForIntPtr(IntPtr f
{
lock (s_functionPositions)
{
- IDebugFunctionPosition2 functionPosition;
- if (!s_functionPositions.TryGet((int)functionPositionId, out functionPosition))
+ if (!s_functionPositions.TryGet((int)functionPositionId, out IDebugFunctionPosition2? functionPosition))
{
throw new ArgumentOutOfRangeException(nameof(functionPositionId));
}
@@ -134,8 +132,7 @@ public static IDebugCodeContext2 GetDebugCodeContextForIntPtr(IntPtr contextId)
{
lock (s_codeContexts)
{
- IDebugCodeContext2 codeContext;
- if (!s_codeContexts.TryGet(contextId.ToInt32(), out codeContext))
+ if (!s_codeContexts.TryGet(contextId.ToInt32(), out IDebugCodeContext2? codeContext))
{
throw new ArgumentOutOfRangeException(nameof(contextId));
}
diff --git a/src/DebugEngineHost.VSCode/HostNatvisProject.cs b/src/DebugEngineHost.VSCode/HostNatvisProject.cs
index e24c4f812..a9c7855e2 100644
--- a/src/DebugEngineHost.VSCode/HostNatvisProject.cs
+++ b/src/DebugEngineHost.VSCode/HostNatvisProject.cs
@@ -14,13 +14,13 @@ public static void FindNatvis(NatvisLoader loader)
// In-solution natvis is not supported for VS Code now, so do nothing.
}
- public static IDisposable WatchNatvisOptionSetting(HostConfigurationStore configStore, ILogChannel natvisLogger)
+ public static IDisposable? WatchNatvisOptionSetting(HostConfigurationStore configStore, ILogChannel natvisLogger)
{
// VS Code does not have a registry setting for Natvis Diagnostics
return null;
}
- public static string FindSolutionRoot()
+ public static string? FindSolutionRoot()
{
// This was added in MIEngine to support breakpoint sourcefile mapping.
// TODO: Return the project root if we want a similar implementation.
diff --git a/src/DebugEngineHost.VSCode/HostOutputWindow.cs b/src/DebugEngineHost.VSCode/HostOutputWindow.cs
index 63b249ab6..eba011b40 100644
--- a/src/DebugEngineHost.VSCode/HostOutputWindow.cs
+++ b/src/DebugEngineHost.VSCode/HostOutputWindow.cs
@@ -2,13 +2,12 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
-using System.Diagnostics;
namespace Microsoft.DebugEngineHost
{
public static class HostOutputWindow
{
- private static Action s_launchErrorCallback;
+ private static Action? s_launchErrorCallback;
public static void InitializeLaunchErrorCallback(Action launchErrorCallback)
{
@@ -18,7 +17,7 @@ public static void InitializeLaunchErrorCallback(Action launchErrorCallb
public static void WriteLaunchError(string outputMessage)
{
- if (s_launchErrorCallback != null)
+ if (s_launchErrorCallback is not null)
{
s_launchErrorCallback(outputMessage);
}
diff --git a/src/DebugEngineHost.VSCode/HostRunInTerminal.cs b/src/DebugEngineHost.VSCode/HostRunInTerminal.cs
index b8c94e835..60dbcf109 100644
--- a/src/DebugEngineHost.VSCode/HostRunInTerminal.cs
+++ b/src/DebugEngineHost.VSCode/HostRunInTerminal.cs
@@ -3,14 +3,13 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
namespace Microsoft.DebugEngineHost
{
public static class HostRunInTerminal
{
- private static Action, Dictionary, Action, Action> s_runInTerminalCallback;
+ private static Action, Dictionary, Action, Action>? s_runInTerminalCallback;
///
/// Checks to see if RunInTerminal is available
@@ -18,7 +17,7 @@ public static class HostRunInTerminal
///
public static bool IsRunInTerminalAvailable()
{
- return s_runInTerminalCallback != null;
+ return s_runInTerminalCallback is not null;
}
///
@@ -26,7 +25,7 @@ public static bool IsRunInTerminalAvailable()
///
public static void RunInTerminal(string title, string cwd, bool useExternalConsole, IReadOnlyList commandArgs, IReadOnlyDictionary environmentVars, Action success, Action failure)
{
- if (s_runInTerminalCallback != null)
+ if (s_runInTerminalCallback is not null)
{
Dictionary env = new Dictionary();
foreach (var item in environmentVars)
diff --git a/src/DebugEngineHost.VSCode/HostTelemetry.cs b/src/DebugEngineHost.VSCode/HostTelemetry.cs
index 0eed205ce..0801a507e 100644
--- a/src/DebugEngineHost.VSCode/HostTelemetry.cs
+++ b/src/DebugEngineHost.VSCode/HostTelemetry.cs
@@ -3,7 +3,7 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics;
+using ConditionalAttribute = global::System.Diagnostics.ConditionalAttribute;
using System.Linq;
using System.Reflection;
@@ -29,11 +29,11 @@ public static class HostTelemetry
private const string TelemetryHostVersion = @"VS.Diagnostics.Debugger.HostVersion";
private const string TelemetryAdapterId = @"VS.Diagnostics.Debugger.AdapterId";
- private static Action[]> s_telemetryCallback;
- private static string s_engineName;
- private static string s_engineVersion;
- private static string s_hostVersion;
- private static string s_adapterId;
+ private static Action[]>? s_telemetryCallback;
+ private static string? s_engineName;
+ private static string? s_engineVersion;
+ private static string? s_hostVersion;
+ private static string? s_adapterId;
public static void InitializeTelemetry(Action[]> telemetryCallback, TypeInfo engineType, string adapterId)
{
@@ -56,7 +56,7 @@ public static void InitializeTelemetry(Action[] eventProperties)
{
#if LAB
- if (s_telemetryCallback != null)
+ if (s_telemetryCallback is not null)
{
s_telemetryCallback(eventName, eventProperties);
}
@@ -70,34 +70,35 @@ public static void SendEvent(string eventName, params KeyValuePairException object to report.
/// [Optional] Name of the engine reporting the exception. Ex:Microsoft.MIEngine.
/// In OpenDebugAD7, this is optional.
- public static void ReportCurrentException(Exception currentException, string engineName)
+ public static void ReportCurrentException(Exception currentException, string? engineName)
{
try
{
// Report the inner-most exception
- while (currentException.InnerException != null)
+ while (currentException.InnerException is not null)
{
currentException = currentException.InnerException;
}
- if (s_hostVersion == null)
+ if (s_hostVersion is null)
{
// InitializeTelemetry not called yet
return;
}
- if (engineName == null)
+ if (engineName is null)
{
+ Debug.Assert(s_engineName is not null, "Should be impossible -- if we got past the previous check, InitializeTelemetry was already called");
engineName = s_engineName;
}
SendEvent(TelemetryNonFatalWatsonEventName,
new KeyValuePair(TelemetryNonFatalErrorImplementationName, engineName),
- new KeyValuePair(TelemetryNonFatalErrorExceptionTypeName, currentException.GetType().FullName),
- new KeyValuePair(TelemetryNonFatalErrorExceptionStackName, currentException.StackTrace),
+ new KeyValuePair(TelemetryNonFatalErrorExceptionTypeName, currentException.GetType().FullName ?? string.Empty),
+ new KeyValuePair(TelemetryNonFatalErrorExceptionStackName, currentException.StackTrace ?? string.Empty),
new KeyValuePair(TelemetryNonFatalErrorExceptionHResult, currentException.HResult),
- new KeyValuePair(TelemetryEngineVersion, s_engineVersion),
- new KeyValuePair(TelemetryAdapterId, s_adapterId),
+ new KeyValuePair(TelemetryEngineVersion, s_engineVersion ?? string.Empty),
+ new KeyValuePair(TelemetryAdapterId, s_adapterId ?? string.Empty),
new KeyValuePair(TelemetryHostVersion, s_hostVersion)
);
}
@@ -110,7 +111,7 @@ public static void ReportCurrentException(Exception currentException, string eng
private static string GetVersionAttributeValue(TypeInfo engineType)
{
var attribute = engineType.Assembly.GetCustomAttribute(typeof(System.Reflection.AssemblyFileVersionAttribute)) as AssemblyFileVersionAttribute;
- if (attribute == null)
+ if (attribute is null)
return string.Empty;
return attribute.Version;
diff --git a/src/DebugEngineHost.VSCode/VSCode/AssemblyResolver.cs b/src/DebugEngineHost.VSCode/VSCode/AssemblyResolver.cs
index e8b46a10d..943379461 100644
--- a/src/DebugEngineHost.VSCode/VSCode/AssemblyResolver.cs
+++ b/src/DebugEngineHost.VSCode/VSCode/AssemblyResolver.cs
@@ -19,18 +19,18 @@ public static void Initialize()
AssemblyLoadContext.Default.Resolving += OnAssemblyResolve;
}
- private static Assembly OnAssemblyResolve(AssemblyLoadContext loadContext, AssemblyName assemblyName)
+ private static Assembly? OnAssemblyResolve(AssemblyLoadContext loadContext, AssemblyName assemblyName)
{
- Assembly asm = InnerResolveHandler(assemblyName);
+ Assembly? asm = InnerResolveHandler(assemblyName);
return asm;
}
- private static Assembly InnerResolveHandler(AssemblyName assemblyName)
+ private static Assembly? InnerResolveHandler(AssemblyName assemblyName)
{
string assemblyFileName = string.Concat(assemblyName.Name, ".dll");
- if (assemblyName.CultureInfo != null && !assemblyName.CultureInfo.Equals(CultureInfo.InvariantCulture))
+ if (assemblyName.CultureInfo is not null && !assemblyName.CultureInfo.Equals(CultureInfo.InvariantCulture))
{
//Prepend the culture directory (e.g. ja\Microsoft.VisualStudio.Test.resources.dll)
assemblyFileName = Path.Combine(assemblyName.CultureInfo.Name, assemblyFileName);
@@ -45,9 +45,9 @@ private static Assembly InnerResolveHandler(AssemblyName assemblyName)
}
}
- Assembly asm = AssemblyLoadContext.Default.LoadFromAssemblyPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assemblyFileName));
+ Assembly? asm = AssemblyLoadContext.Default.LoadFromAssemblyPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assemblyFileName));
- if (asm == null)
+ if (asm is null)
{
lock (s_unresolvedNames)
{
diff --git a/src/DebugEngineHost.VSCode/VSCode/EngineConfiguration.cs b/src/DebugEngineHost.VSCode/VSCode/EngineConfiguration.cs
index 265d4246c..678a9d20d 100644
--- a/src/DebugEngineHost.VSCode/VSCode/EngineConfiguration.cs
+++ b/src/DebugEngineHost.VSCode/VSCode/EngineConfiguration.cs
@@ -21,14 +21,14 @@ namespace Microsoft.DebugEngineHost.VSCode
{
public sealed class EngineConfiguration
{
- private static string s_adapterDirectory;
+ private static string? s_adapterDirectory;
private static readonly Dictionary s_dict = new Dictionary();
- public string AdapterId { get; private set; }
+ public string AdapterId { get; private set; } = null!;
private bool _isReadOnly;
- private string _assemblyName;
- private string _engineClass;
+ private string _assemblyName = null!;
+ private string _engineClass = null!;
private readonly ExceptionSettings _exceptionSettings = new ExceptionSettings();
private bool _conditionalBP;
private bool _functionBP;
@@ -89,14 +89,14 @@ public bool DataBP
/// Path to the directory
public static string GetAdapterDirectory()
{
- if (s_adapterDirectory == null)
+ if (s_adapterDirectory is null)
{
// Configuration goes in the directory of this assembly
string thisModulePath = typeof(EngineConfiguration).GetTypeInfo().Assembly.ManifestModule.FullyQualifiedName;
Interlocked.CompareExchange(ref s_adapterDirectory, Path.GetDirectoryName(thisModulePath), null);
}
- return s_adapterDirectory;
+ return s_adapterDirectory!;
}
///
@@ -107,7 +107,7 @@ public static string GetAdapterDirectory()
/// The directory to use.
public static void SetAdapterDirectory(string adapterDirectory)
{
- if (adapterDirectory == null)
+ if (adapterDirectory is null)
{
throw new ArgumentNullException(nameof(adapterDirectory));
}
@@ -118,11 +118,11 @@ public static void SetAdapterDirectory(string adapterDirectory)
}
}
- public static EngineConfiguration TryGet(string adapterId)
+ public static EngineConfiguration? TryGet(string adapterId)
{
lock (s_dict)
{
- EngineConfiguration result;
+ EngineConfiguration? result;
if (s_dict.TryGetValue(adapterId, out result))
{
return result;
@@ -131,6 +131,10 @@ public static EngineConfiguration TryGet(string adapterId)
string engineConfigPath = Path.Combine(GetAdapterDirectory(), adapterId + ".ad7Engine.json");
string engineConfigText = File.ReadAllText(engineConfigPath);
result = JsonConvert.DeserializeObject(engineConfigText);
+ if (result is null)
+ {
+ return null;
+ }
result.AdapterId = adapterId;
result.ExceptionSettings.MakeReadOnly();
result._isReadOnly = true;
@@ -149,15 +153,15 @@ public object LoadEngine()
AssemblyName assemblyName = new System.Reflection.AssemblyName(this.EngineAssemblyName);
Assembly engineAssembly = Assembly.Load(assemblyName);
- Type engineClass = engineAssembly.GetType(this.EngineClassName);
- if (engineClass == null)
+ Type? engineClass = engineAssembly.GetType(this.EngineClassName);
+ if (engineClass is null)
{
throw new InvalidDataException(string.Format(CultureInfo.CurrentCulture, HostResources.Error_ClassNotFound, this.EngineClassName, this.EngineAssemblyName));
}
- object instance = Activator.CreateInstance(engineClass);
+ object? instance = Activator.CreateInstance(engineClass);
- if (instance == null)
+ if (instance is null)
{
throw new InvalidDataException(string.Format(CultureInfo.CurrentCulture, HostResources.Error_ConstructorNotFound, this.EngineClassName, this.EngineAssemblyName));
}
diff --git a/src/DebugEngineHost.VSCode/VSCode/ExceptionBreakpointFilter.cs b/src/DebugEngineHost.VSCode/VSCode/ExceptionBreakpointFilter.cs
index 6e2064e84..618c28b7d 100644
--- a/src/DebugEngineHost.VSCode/VSCode/ExceptionBreakpointFilter.cs
+++ b/src/DebugEngineHost.VSCode/VSCode/ExceptionBreakpointFilter.cs
@@ -4,7 +4,6 @@
using Microsoft.VisualStudio.Debugger.Interop;
using Newtonsoft.Json;
using System;
-using System.Diagnostics;
namespace Microsoft.DebugEngineHost.VSCode
{
@@ -14,13 +13,13 @@ namespace Microsoft.DebugEngineHost.VSCode
///
sealed public class ExceptionBreakpointFilter
{
- private string _filter;
+ private string _filter = null!;
///
/// The label for the button that will appear in the UI
///
[JsonRequired]
- public string label { get; set; }
+ public string label { get; set; } = null!;
///
/// The identifier for this filter.
@@ -43,7 +42,7 @@ public string filter
public bool supportsCondition { get; set; }
[JsonRequired]
- public string conditionDescription { get; set; }
+ public string conditionDescription { get; set; } = null!;
[JsonRequired]
public Guid categoryId { get; set; }
diff --git a/src/DebugEngineHost.VSCode/VSCode/ExceptionSettings.cs b/src/DebugEngineHost.VSCode/VSCode/ExceptionSettings.cs
index 2328784ff..980a18831 100644
--- a/src/DebugEngineHost.VSCode/VSCode/ExceptionSettings.cs
+++ b/src/DebugEngineHost.VSCode/VSCode/ExceptionSettings.cs
@@ -6,7 +6,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
-using System.Diagnostics;
using System.Globalization;
using System.Linq;
@@ -26,7 +25,7 @@ public enum TriggerState
sealed public class CategoryConfiguration
{
[JsonRequired]
- public string Name;
+ public string Name = null!;
[JsonRequired]
public Guid Id;
diff --git a/src/DebugEngineHost.VSCode/VSCode/HandleCollection.cs b/src/DebugEngineHost.VSCode/VSCode/HandleCollection.cs
index 1d23ea8a7..902dc0b4e 100644
--- a/src/DebugEngineHost.VSCode/VSCode/HandleCollection.cs
+++ b/src/DebugEngineHost.VSCode/VSCode/HandleCollection.cs
@@ -5,6 +5,7 @@
using System;
using System.Linq;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
namespace Microsoft.DebugEngineHost.VSCode
{
@@ -34,7 +35,7 @@ public int Create(T value)
return handle;
}
- public bool TryGet(int handle, out T value)
+ public bool TryGet(int handle, [MaybeNullWhen(false)] out T value)
{
if (_handleMap.TryGetValue(handle, out value))
{
@@ -43,11 +44,11 @@ public bool TryGet(int handle, out T value)
return false;
}
- public bool TryGetFirst(out T value)
+ public bool TryGetFirst([MaybeNullWhen(false)] out T value)
{
if (IsEmpty)
{
- value = default(T);
+ value = default;
return false;
}
@@ -58,8 +59,7 @@ public T this[int handle]
{
get
{
- T value;
- if (!TryGet(handle, out value))
+ if (!TryGet(handle, out T? value))
{
throw new ArgumentOutOfRangeException(nameof(handle));
}
diff --git a/src/DebugEngineHost/DebugEngineHost.csproj b/src/DebugEngineHost/DebugEngineHost.csproj
index a0f375ed7..66706dea0 100755
--- a/src/DebugEngineHost/DebugEngineHost.csproj
+++ b/src/DebugEngineHost/DebugEngineHost.csproj
@@ -3,6 +3,7 @@
1.0.0
+ enable
@@ -26,11 +27,16 @@
$(VSSDKRoot)VisualStudioIntegration\Common\Assemblies\v4.0\Microsoft.VisualStudio.Debugger.Engine.dll
-
-
-
-
-
+
+
+ Shared\%(Filename).cs
+
+
+ Shared\%(Filename).cs
+
+
+ Shared\%(Filename).cs
+
diff --git a/src/DebugEngineHost/FeedbackDiagnosticFileProvider.cs b/src/DebugEngineHost/FeedbackDiagnosticFileProvider.cs
index db4a5f58b..07b9bb79e 100644
--- a/src/DebugEngineHost/FeedbackDiagnosticFileProvider.cs
+++ b/src/DebugEngineHost/FeedbackDiagnosticFileProvider.cs
@@ -1,13 +1,13 @@
-// Copyright (c) Microsoft. All rights reserved.
+// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
-using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Internal.VisualStudio.Shell.Embeddable.Feedback;
+using Process = global::System.Diagnostics.Process;
namespace Microsoft.DebugEngineHost
{
diff --git a/src/DebugEngineHost/Host.cs b/src/DebugEngineHost/Host.cs
index 62e634ff8..40e1d8bf5 100644
--- a/src/DebugEngineHost/Host.cs
+++ b/src/DebugEngineHost/Host.cs
@@ -1,9 +1,8 @@
-// Copyright (c) Microsoft. All rights reserved.
+// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
diff --git a/src/DebugEngineHost/HostConfigurationSection.cs b/src/DebugEngineHost/HostConfigurationSection.cs
index 7f3f3f402..5a037f5ee 100644
--- a/src/DebugEngineHost/HostConfigurationSection.cs
+++ b/src/DebugEngineHost/HostConfigurationSection.cs
@@ -30,7 +30,7 @@ public void Dispose()
///
/// Name of the value to obtain
/// [Optional] null if the value doesn't exist, otherwise the value
- public object GetValue(string valueName)
+ public object? GetValue(string valueName)
{
return _key.GetValue(valueName);
}
diff --git a/src/DebugEngineHost/HostConfigurationStore.cs b/src/DebugEngineHost/HostConfigurationStore.cs
index 1f491a3d9..787d8359b 100644
--- a/src/DebugEngineHost/HostConfigurationStore.cs
+++ b/src/DebugEngineHost/HostConfigurationStore.cs
@@ -1,10 +1,9 @@
-// Copyright (c) Microsoft. All rights reserved.
+// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Win32;
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -21,7 +20,7 @@ public sealed class HostConfigurationStore
private const string LaunchersSectionName = "MILaunchers";
private const string NatvisDiagnosticsSectionName = "NatvisDiagnostics";
- private string _engineId;
+ private string? _engineId;
private string _registryRoot;
// HKLM RegistryKey
@@ -29,15 +28,16 @@ public sealed class HostConfigurationStore
public HostConfigurationStore(string registryRoot)
{
- if (string.IsNullOrEmpty(registryRoot))
+ if (IsNullOrEmpty(registryRoot))
throw new ArgumentNullException(nameof(registryRoot));
_registryRoot = registryRoot;
- _configKey = Registry.LocalMachine.OpenSubKey(registryRoot);
- if (_configKey == null)
+ RegistryKey? configKey = Registry.LocalMachine.OpenSubKey(registryRoot);
+ if (configKey is null)
{
throw new HostConfigurationException(registryRoot);
}
+ _configKey = configKey;
}
///
@@ -46,7 +46,7 @@ public HostConfigurationStore(string registryRoot)
/// The new engine GUID to set
public void SetEngineGuid(Guid value)
{
- if (_engineId != null)
+ if (_engineId is not null)
{
throw new InvalidOperationException();
}
@@ -63,9 +63,9 @@ public string RegistryRoot
}
}
- public object GetEngineMetric(string metric)
+ public object? GetEngineMetric(string metric)
{
- if (_engineId == null)
+ if (_engineId is null)
{
throw new InvalidOperationException();
}
@@ -76,8 +76,8 @@ public object GetEngineMetric(string metric)
public void GetExceptionCategorySettings(Guid categoryId, out HostConfigurationSection categoryConfigSection, out string categoryName)
{
string subKeyName = @"AD7Metrics\Exception\" + categoryId.ToString("B", CultureInfo.InvariantCulture);
- RegistryKey categoryKey = _configKey.OpenSubKey(subKeyName);
- if (categoryKey == null)
+ RegistryKey? categoryKey = _configKey.OpenSubKey(subKeyName);
+ if (categoryKey is null)
{
throw new HostConfigurationException("$RegRoot$\\" + subKeyName);
}
@@ -91,7 +91,7 @@ public T GetDebuggerConfigurationSetting(string settingName, T defaultValue)
return GetDebuggerConfigurationSetting(DebuggerSectionName, settingName, defaultValue);
}
- public object GetCustomLauncher(string launcherTypeName)
+ public object? GetCustomLauncher(string launcherTypeName)
{
string guidstr = GetDebuggerConfigurationSetting(LaunchersSectionName, launcherTypeName, Guid.Empty.ToString());
Guid clsidLauncher = new Guid(guidstr);
@@ -104,8 +104,8 @@ public object GetCustomLauncher(string launcherTypeName)
private T GetDebuggerConfigurationSetting(string sectionName, string settingName, T defaultValue)
{
- object valueObj = GetOptionalValue(sectionName, settingName);
- if (valueObj == null)
+ object? valueObj = GetOptionalValue(sectionName, settingName);
+ if (valueObj is null)
{
return defaultValue;
}
@@ -124,11 +124,11 @@ private T GetDebuggerConfigurationSetting(string sectionName, string settingN
return result;
}
- private object GetOptionalValue(string section, string valueName)
+ private object? GetOptionalValue(string section, string valueName)
{
- using (RegistryKey key = _configKey.OpenSubKey(section))
+ using (RegistryKey? key = _configKey.OpenSubKey(section))
{
- if (key == null)
+ if (key is null)
{
return null;
}
@@ -141,12 +141,17 @@ private object GetOptionalValue(string section, string valueName)
/// This method grabs the Debugger Subkey in HKCU
///
/// The subkey of Debugger if it exists. Returns null otherwise.
- public HostConfigurationSection GetCurrentUserDebuggerSection()
+ public HostConfigurationSection? GetCurrentUserDebuggerSection()
{
- using (RegistryKey hkcuRoot = Registry.CurrentUser.OpenSubKey(_registryRoot))
+ using (RegistryKey? hkcuRoot = Registry.CurrentUser.OpenSubKey(_registryRoot))
{
- RegistryKey debuggerSection = hkcuRoot.OpenSubKey(DebuggerSectionName);
- if (debuggerSection != null)
+ if (hkcuRoot is null)
+ {
+ return null;
+ }
+
+ RegistryKey? debuggerSection = hkcuRoot.OpenSubKey(DebuggerSectionName);
+ if (debuggerSection is not null)
{
return new HostConfigurationSection(debuggerSection);
}
@@ -158,16 +163,21 @@ public HostConfigurationSection GetCurrentUserDebuggerSection()
/// Grabs the Debugger/NatvisDiagnostic subkey in HKCU
///
/// The NatvisDiagnostic subkey if it exists. Returns null otherwise.
- public HostConfigurationSection GetNatvisDiagnosticSection()
+ public HostConfigurationSection? GetNatvisDiagnosticSection()
{
- using (RegistryKey hkcuRoot = Registry.CurrentUser.OpenSubKey(_registryRoot))
+ using (RegistryKey? hkcuRoot = Registry.CurrentUser.OpenSubKey(_registryRoot))
{
- using (RegistryKey debuggerSection = hkcuRoot.OpenSubKey(DebuggerSectionName))
+ if (hkcuRoot is null)
+ {
+ return null;
+ }
+
+ using (RegistryKey? debuggerSection = hkcuRoot.OpenSubKey(DebuggerSectionName))
{
- if (debuggerSection != null)
+ if (debuggerSection is not null)
{
- RegistryKey natvisDiagnosticKey = debuggerSection.OpenSubKey(NatvisDiagnosticsSectionName);
- if (natvisDiagnosticKey != null)
+ RegistryKey? natvisDiagnosticKey = debuggerSection.OpenSubKey(NatvisDiagnosticsSectionName);
+ if (natvisDiagnosticKey is not null)
{
return new HostConfigurationSection(natvisDiagnosticKey);
}
diff --git a/src/DebugEngineHost/HostLoader.cs b/src/DebugEngineHost/HostLoader.cs
index 84d666298..f19f6bc97 100644
--- a/src/DebugEngineHost/HostLoader.cs
+++ b/src/DebugEngineHost/HostLoader.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft. All rights reserved.
+// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Win32;
@@ -23,21 +23,24 @@ public static class HostLoader
/// Registry root to lookup the type
/// CLSID to CoCreate
/// [Optional] loaded object. Null if the type is not registered, or points to a type that doesn't exist
- public static object VsCoCreateManagedObject(HostConfigurationStore configStore, Guid clsid)
+ public static object? VsCoCreateManagedObject(HostConfigurationStore configStore, Guid clsid)
{
- string assemblyNameString, className, codeBase;
+ string? assemblyNameString, className, codeBase;
if (!GetManagedTypeInfoForCLSID(configStore, clsid, out assemblyNameString, out className, out codeBase))
{
return null;
}
- if (codeBase != null && !File.Exists(codeBase))
+ Debug.Assert(assemblyNameString is not null, "assemblyNameString should be set when GetManagedTypeInfoForCLSID returns true");
+ Debug.Assert(className is not null, "className should be set when GetManagedTypeInfoForCLSID returns true");
+
+ if (codeBase is not null && !File.Exists(codeBase))
{
return null;
}
AssemblyName assemblyName = new AssemblyName(assemblyNameString);
- if (codeBase != null)
+ if (codeBase is not null)
{
assemblyName.CodeBase = "file:///" + codeBase;
}
@@ -46,34 +49,34 @@ public static object VsCoCreateManagedObject(HostConfigurationStore configStore,
return assemblyObject.CreateInstance(className);
}
- private static bool GetManagedTypeInfoForCLSID(HostConfigurationStore configStore, Guid clsid, out string assembly, out string className, out string codeBase)
+ private static bool GetManagedTypeInfoForCLSID(HostConfigurationStore configStore, Guid clsid, out string? assembly, out string? className, out string? codeBase)
{
assembly = null;
className = null;
codeBase = null;
string keyPath = configStore.RegistryRoot + @"\CLSID\" + clsid.ToString("B");
- using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyPath))
+ using (RegistryKey? key = Registry.LocalMachine.OpenSubKey(keyPath))
{
- if (key == null)
+ if (key is null)
return false;
- object oAssembly = key.GetValue("Assembly");
- object oClassName = key.GetValue("Class");
- object oCodeBase = key.GetValue("CodeBase");
+ object? oAssembly = key.GetValue("Assembly");
+ object? oClassName = key.GetValue("Class");
+ object? oCodeBase = key.GetValue("CodeBase");
- if (oAssembly == null || !(oAssembly is string))
+ if (oAssembly is not string)
return false;
- if (oClassName == null || !(oClassName is string))
+ if (oClassName is not string)
return false;
// CodeBase is not required, but it is an error if it isn't a string
- if (oCodeBase != null && !(oCodeBase is string))
+ if (oCodeBase is not null and not string)
return false;
assembly = (string)oAssembly;
className = (string)oClassName;
- codeBase = (string)oCodeBase;
+ codeBase = oCodeBase as string;
return true;
}
diff --git a/src/DebugEngineHost/HostLogger.cs b/src/DebugEngineHost/HostLogger.cs
index fbeca7eb4..ab29a977f 100644
--- a/src/DebugEngineHost/HostLogger.cs
+++ b/src/DebugEngineHost/HostLogger.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft. All rights reserved.
+// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
@@ -11,22 +11,22 @@ namespace Microsoft.DebugEngineHost
{
public static class HostLogger
{
- private static ILogChannel s_natvisLogChannel;
- private static ILogChannel s_engineLogChannel;
+ private static ILogChannel? s_natvisLogChannel;
+ private static ILogChannel? s_engineLogChannel;
- private static string s_engineLogFile;
+ private static string? s_engineLogFile;
- private static FeedbackLogBuffer s_circularBuffer;
- private static VSFeedbackLogger s_feedbackLogger;
+ private static FeedbackLogBuffer? s_circularBuffer;
+ private static VSFeedbackLogger? s_feedbackLogger;
public static void EnableHostLogging(Action callback, LogLevel level = LogLevel.Verbose)
{
- if (s_engineLogChannel == null)
+ if (s_engineLogChannel is null)
{
s_engineLogChannel = new HostLogChannel(callback, s_engineLogFile, level);
}
- if (s_feedbackLogger == null)
+ if (s_feedbackLogger is null)
{
s_feedbackLogger = new VSFeedbackLogger(EnsureFeedbackBuffer());
}
@@ -34,7 +34,7 @@ public static void EnableHostLogging(Action callback, LogLevel level = L
public static void EnableNatvisDiagnostics(Action callback, LogLevel level = LogLevel.Verbose)
{
- if (s_natvisLogChannel== null)
+ if (s_natvisLogChannel is null)
{
s_natvisLogChannel = new HostLogChannel(callback, null, level);
}
@@ -45,17 +45,17 @@ public static void DisableNatvisDiagnostics()
s_natvisLogChannel = null;
}
- public static void SetEngineLogFile(string logFile)
+ public static void SetEngineLogFile(string? logFile)
{
s_engineLogFile = logFile;
}
- public static ILogChannel GetEngineLogChannel()
+ public static ILogChannel? GetEngineLogChannel()
{
return s_engineLogChannel;
}
- public static ILogChannel GetNatvisLogChannel()
+ public static ILogChannel? GetNatvisLogChannel()
{
return s_natvisLogChannel;
}
@@ -65,7 +65,7 @@ public static ILogChannel GetNatvisLogChannel()
///
public static bool IsFeedbackLogEnabled
{
- get { return s_circularBuffer != null; }
+ get { return s_circularBuffer is not null; }
}
///
@@ -73,7 +73,7 @@ public static bool IsFeedbackLogEnabled
///
public static void WriteFeedbackLog(string message)
{
- if (string.IsNullOrEmpty(message))
+ if (IsNullOrEmpty(message))
{
return;
}
@@ -87,7 +87,7 @@ public static void WriteFeedbackLog(string message)
private static FeedbackLogBuffer EnsureFeedbackBuffer()
{
- if (s_circularBuffer == null)
+ if (s_circularBuffer is null)
{
Interlocked.CompareExchange(ref s_circularBuffer, new FeedbackLogBuffer(), null);
}
@@ -102,8 +102,8 @@ internal static bool HasFeedbackEntries
{
get
{
- FeedbackLogBuffer buffer = s_circularBuffer;
- return buffer != null && buffer.HasEntries;
+ FeedbackLogBuffer? buffer = s_circularBuffer;
+ return buffer is not null && buffer.HasEntries;
}
}
diff --git a/src/DebugEngineHost/HostMarshal.cs b/src/DebugEngineHost/HostMarshal.cs
index d3d6f1844..9c249c2af 100644
--- a/src/DebugEngineHost/HostMarshal.cs
+++ b/src/DebugEngineHost/HostMarshal.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft. All rights reserved.
+// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.VisualStudio.Debugger.Interop;
@@ -8,7 +8,6 @@
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
-using System.Diagnostics;
namespace Microsoft.DebugEngineHost
{
diff --git a/src/DebugEngineHost/HostNatvisProject.cs b/src/DebugEngineHost/HostNatvisProject.cs
index 11c3510eb..a86b8063d 100644
--- a/src/DebugEngineHost/HostNatvisProject.cs
+++ b/src/DebugEngineHost/HostNatvisProject.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft. All rights reserved.
+// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
@@ -34,7 +34,7 @@ internal RegisterMonitorWrapper(RegistryMonitor currentMonitor)
public void Dispose()
{
CurrentMonitor.Dispose();
- CurrentMonitor = null;
+ CurrentMonitor = null!;
}
}
@@ -66,12 +66,12 @@ public static void FindNatvis(NatvisLoader loader)
paths.ForEach((s) => loader(s));
}
- public static IDisposable WatchNatvisOptionSetting(HostConfigurationStore configStore, ILogChannel natvisLogger)
+ public static IDisposable? WatchNatvisOptionSetting(HostConfigurationStore configStore, ILogChannel natvisLogger)
{
- RegisterMonitorWrapper rmw = null;
+ RegisterMonitorWrapper? rmw = null;
- HostConfigurationSection natvisDiagnosticSection = configStore.GetNatvisDiagnosticSection();
- if (natvisDiagnosticSection != null)
+ HostConfigurationSection? natvisDiagnosticSection = configStore.GetNatvisDiagnosticSection();
+ if (natvisDiagnosticSection is not null)
{
// DiagnosticSection exists, set current log level and watch for changes.
SetNatvisLogLevel(natvisDiagnosticSection);
@@ -81,9 +81,9 @@ public static IDisposable WatchNatvisOptionSetting(HostConfigurationStore config
else
{
// NatvisDiagnostic section has not been created, we need to watch for the creation.
- HostConfigurationSection debuggerSection = configStore.GetCurrentUserDebuggerSection();
+ HostConfigurationSection? debuggerSection = configStore.GetCurrentUserDebuggerSection();
- if (debuggerSection != null)
+ if (debuggerSection is not null)
{
// We only care about the debugger subkey's keys since we are waiting for the NatvisDiagnostics
// section to be created.
@@ -93,9 +93,9 @@ public static IDisposable WatchNatvisOptionSetting(HostConfigurationStore config
rm.RegChanged += (sender, e) =>
{
- HostConfigurationSection checkForSection = configStore.GetNatvisDiagnosticSection();
+ HostConfigurationSection? checkForSection = configStore.GetNatvisDiagnosticSection();
- if (checkForSection != null)
+ if (checkForSection is not null)
{
// NatvisDiagnostic section found. Update the logger
SetNatvisLogLevel(checkForSection);
@@ -134,8 +134,8 @@ private static RegistryMonitor CreateAndStartNatvisDiagnosticMonitor(HostConfigu
private static void SetNatvisLogLevel(HostConfigurationSection natvisDiagnosticSection)
{
- string level = natvisDiagnosticSection.GetValue("Level") as string;
- if (level != null)
+ string? level = natvisDiagnosticSection.GetValue("Level") as string;
+ if (level is not null)
{
level = level.ToLower(CultureInfo.InvariantCulture);
}
@@ -169,13 +169,13 @@ private static void SetNatvisLogLevel(HostConfigurationSection natvisDiagnosticS
string formattedMessage = string.Format(CultureInfo.InvariantCulture, "Natvis: {0}", message);
HostOutputWindow.WriteLaunchError(formattedMessage);
}, logLevel);
- HostLogger.GetNatvisLogChannel().SetLogLevel(logLevel);
+ HostLogger.GetNatvisLogChannel()!.SetLogLevel(logLevel);
}
}
- public static string FindSolutionRoot()
+ public static string? FindSolutionRoot()
{
- string path = null;
+ string? path = null;
try
{
ThreadHelper.JoinableTaskFactory.Run(async () =>
@@ -217,14 +217,14 @@ internal enum VSENUMPROJFLAGS
/// Gets the WorkspaceService from Microsoft.VisualStudio.Workspace
///
/// This package won't be automatically loaded by MEF, so we need to manually acquire exported MEF Parts.
- private static IVsFolderWorkspaceService GetWorkspaceService()
+ private static IVsFolderWorkspaceService? GetWorkspaceService()
{
- IComponentModel componentModel = ServiceProvider.GlobalProvider.GetService(typeof(SComponentModel).GUID) as IComponentModel;
- if (componentModel != null)
+ IComponentModel? componentModel = ServiceProvider.GlobalProvider.GetService(typeof(SComponentModel).GUID) as IComponentModel;
+ if (componentModel is not null)
{
var workspaceServices = componentModel.DefaultExportProvider.GetExports();
- if (workspaceServices != null && workspaceServices.Any())
+ if (workspaceServices is not null && workspaceServices.Any())
{
return workspaceServices.First().Value;
}
@@ -237,11 +237,11 @@ private async static Task> GetOpenFolderSourceLocationsAsync
var workspaceService = GetWorkspaceService();
IEnumerable sourcesArray = new List();
- if (workspaceService != null)
+ if (workspaceService is not null)
{
- IWorkspace currentWorkspace = workspaceService.CurrentWorkspace;
- IIndexWorkspaceService indexWorkspaceService = currentWorkspace?.GetService(throwIfNotFound: false);
- if (indexWorkspaceService != null)
+ IWorkspace? currentWorkspace = workspaceService.CurrentWorkspace;
+ IIndexWorkspaceService? indexWorkspaceService = currentWorkspace?.GetService(throwIfNotFound: false);
+ if (indexWorkspaceService is not null)
{
if (indexWorkspaceService.State != IndexWorkspaceState.Completed)
{
@@ -280,8 +280,8 @@ public void Report(string value)
public async static System.Threading.Tasks.Task FindNatvisInSolutionImplAsync(List paths)
{
- var solution = (IVsSolution)Package.GetGlobalService(typeof(SVsSolution));
- if (solution == null)
+ var solution = Package.GetGlobalService(typeof(SVsSolution)) as IVsSolution;
+ if (solution is null)
{
return; // failed to find a solution
}
@@ -321,8 +321,8 @@ public async static System.Threading.Tasks.Task FindNatvisInSolutionImplAsync(Li
public static void FindNatvisInVSIXImpl(List paths)
{
- var extManager = (IVsExtensionManagerPrivate)Package.GetGlobalService(typeof(SVsExtensionManager));
- if (extManager == null)
+ var extManager = Package.GetGlobalService(typeof(SVsExtensionManager)) as IVsExtensionManagerPrivate;
+ if (extManager is null)
{
return; // failed to find the extension manager
}
@@ -330,13 +330,13 @@ public static void FindNatvisInVSIXImpl(List paths)
BuildEnvironmentPath("NativeCrossPlatformVisualizer", extManager, paths);
}
- public static string FindSolutionRootImpl()
+ public static string? FindSolutionRootImpl()
{
- string root = null;
- string slnFile;
- string slnUserFile;
- var solution = (IVsSolution)Package.GetGlobalService(typeof(SVsSolution));
- if (solution == null)
+ string? root = null;
+ string? slnFile;
+ string? slnUserFile;
+ var solution = (IVsSolution?)Package.GetGlobalService(typeof(SVsSolution));
+ if (solution is null)
{
return null; // failed to find a solution
}
@@ -363,8 +363,8 @@ private static void BuildEnvironmentPath(string name, IVsExtensionManagerPrivate
private static void LoadNatvisFromProject(IVsHierarchy hier, List paths, bool solutionLevel)
{
- IVsProject4 proj = hier as IVsProject4;
- if (proj == null)
+ IVsProject4? proj = hier as IVsProject4;
+ if (proj is null)
{
return;
}
diff --git a/src/DebugEngineHost/HostOutputWindow.cs b/src/DebugEngineHost/HostOutputWindow.cs
index 9dec6445a..b2c54b671 100644
--- a/src/DebugEngineHost/HostOutputWindow.cs
+++ b/src/DebugEngineHost/HostOutputWindow.cs
@@ -1,9 +1,8 @@
-// Copyright (c) Microsoft. All rights reserved.
+// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Threading;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell;
@@ -13,9 +12,9 @@ namespace Microsoft.DebugEngineHost
{
internal static class VsOutputWindowWrapper
{
- private static Lazy outputWindowLazy = new Lazy(() =>
+ private static Lazy outputWindowLazy = new Lazy(() =>
{
- IVsOutputWindow outputWindow = null;
+ IVsOutputWindow? outputWindow = null;
try
{
ThreadHelper.ThrowIfNotOnUIThread();
@@ -28,9 +27,9 @@ internal static class VsOutputWindowWrapper
return outputWindow;
}, LazyThreadSafetyMode.PublicationOnly);
- private static Lazy shellLazy = new Lazy(() =>
+ private static Lazy shellLazy = new Lazy(() =>
{
- IVsUIShell shell = null;
+ IVsUIShell? shell = null;
try
{
ThreadHelper.ThrowIfNotOnUIThread();
@@ -75,8 +74,8 @@ public static void Write(string message, string pane = DefaultOutputPane)
try
{
// Get the Output window
- IVsOutputWindow outputWindow = outputWindowLazy.Value;
- if (outputWindow == null)
+ IVsOutputWindow? outputWindow = outputWindowLazy.Value;
+ if (outputWindow is null)
{
return;
}
@@ -108,10 +107,10 @@ public static void Write(string message, string pane = DefaultOutputPane)
outputPane.Activate();
// Show the output window
- IVsUIShell shell = shellLazy.Value;
- if (shell != null)
+ IVsUIShell? shell = shellLazy.Value;
+ if (shell is not null)
{
- object inputVariant = null;
+ object? inputVariant = null;
shell.PostExecCommand(VSConstants.GUID_VSStandardCommandSet97, (uint)VSConstants.VSStd97CmdID.OutputWindow, 0, ref inputVariant);
}
}
diff --git a/src/DebugEngineHost/HostRunInTerminal.cs b/src/DebugEngineHost/HostRunInTerminal.cs
index db666042f..05079fdd1 100644
--- a/src/DebugEngineHost/HostRunInTerminal.cs
+++ b/src/DebugEngineHost/HostRunInTerminal.cs
@@ -1,4 +1,7 @@
-using System;
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
diff --git a/src/DebugEngineHost/HostTelemetry.cs b/src/DebugEngineHost/HostTelemetry.cs
index eea4a0004..39729b7aa 100644
--- a/src/DebugEngineHost/HostTelemetry.cs
+++ b/src/DebugEngineHost/HostTelemetry.cs
@@ -1,14 +1,14 @@
-// Copyright (c) Microsoft. All rights reserved.
+// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using System.Globalization;
using Microsoft.Internal.VisualStudio.Shell;
+using Conditional = global::System.Diagnostics.ConditionalAttribute;
namespace Microsoft.DebugEngineHost
{
@@ -56,7 +56,7 @@ public static void SendEvent(string eventName, params KeyValuePair
/// Exception object to report.
/// Name of the engine reporting the exception. Ex:Microsoft.MIEngine
- public static void ReportCurrentException(Exception currentException, string engineName)
+ public static void ReportCurrentException(Exception currentException, string? engineName)
{
Debug.Fail(string.Format(CultureInfo.InvariantCulture, "{0} was raised and would normally be reported to telemetry.\n\nStack trace: {1}", currentException.GetType(), currentException.StackTrace));
diff --git a/src/DebugEngineHost/HostWaitDialog.cs b/src/DebugEngineHost/HostWaitDialog.cs
index 5de1eafe0..96216b196 100644
--- a/src/DebugEngineHost/HostWaitDialog.cs
+++ b/src/DebugEngineHost/HostWaitDialog.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft. All rights reserved.
+// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
@@ -17,7 +17,7 @@ namespace Microsoft.DebugEngineHost
///
public sealed class HostWaitDialog : IDisposable
{
- private VSImpl.VSWaitDialog _theDialog;
+ private VSImpl.VSWaitDialog? _theDialog;
public HostWaitDialog(string format, string caption)
{
try
@@ -31,7 +31,7 @@ public HostWaitDialog(string format, string caption)
}
public void ShowWaitDialog(string item)
{
- if (_theDialog != null)
+ if (_theDialog is not null)
{
_theDialog.ShowWaitDialog(item);
}
@@ -39,7 +39,7 @@ public void ShowWaitDialog(string item)
public void EndWaitDialog()
{
- if (_theDialog != null)
+ if (_theDialog is not null)
{
_theDialog.EndWaitDialog();
}
diff --git a/src/DebugEngineHost/HostWaitLoop.cs b/src/DebugEngineHost/HostWaitLoop.cs
index f1edbd281..e6153eef7 100644
--- a/src/DebugEngineHost/HostWaitLoop.cs
+++ b/src/DebugEngineHost/HostWaitLoop.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft. All rights reserved.
+// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
@@ -14,7 +14,7 @@ namespace Microsoft.DebugEngineHost
public sealed class HostWaitLoop
{
private readonly object _progressLock = new object();
- private VSImpl.VsWaitLoop _vsWaitLoop;
+ private VSImpl.VsWaitLoop? _vsWaitLoop;
public HostWaitLoop(string message)
{
@@ -34,7 +34,7 @@ public HostWaitLoop(string message)
/// Text to set.
public void SetText(string text)
{
- _vsWaitLoop.SetText(text);
+ _vsWaitLoop?.SetText(text);
}
///
@@ -46,7 +46,7 @@ public void SetText(string text)
/// Thrown by the JIT if Visual Studio is not installed
public void Wait(WaitHandle launchCompleteHandle, CancellationTokenSource cancellationSource)
{
- if (_vsWaitLoop != null)
+ if (_vsWaitLoop is not null)
{
_vsWaitLoop.Wait(launchCompleteHandle, cancellationSource);
@@ -65,7 +65,7 @@ public void SetProgress(int totalSteps, int currentStep, string progressText)
{
lock (_progressLock)
{
- if (_vsWaitLoop != null)
+ if (_vsWaitLoop is not null)
{
_vsWaitLoop.SetProgress(totalSteps, currentStep, progressText);
}
diff --git a/src/DebugEngineHost/RegistryMonitor.cs b/src/DebugEngineHost/RegistryMonitor.cs
index 0281bc371..d733e2569 100644
--- a/src/DebugEngineHost/RegistryMonitor.cs
+++ b/src/DebugEngineHost/RegistryMonitor.cs
@@ -1,4 +1,4 @@
-// // Copyright (c) Microsoft. All rights reserved.
+// // Copyright (c) Microsoft. All rights reserved.
// // Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Win32;
@@ -9,7 +9,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.InteropServices;
-using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -51,7 +50,7 @@ private static extern int RegNotifyChangeKeyValue(SafeRegistryHandle hKey, bool
private readonly bool _watchSubtree;
// Set when monitoring is stopped
- private AutoResetEvent _stoppedEvent;
+ private AutoResetEvent? _stoppedEvent;
// Members to handle multiple stop calls.
private bool _isStopped = false;
@@ -60,7 +59,7 @@ private static extern int RegNotifyChangeKeyValue(SafeRegistryHandle hKey, bool
///
/// Occurs when the specified registry key has changed.
///
- public event EventHandler RegChanged;
+ public event EventHandler? RegChanged;
private readonly ILogChannel _nativsLogger;
@@ -126,7 +125,7 @@ private void Monitor()
_nativsLogger?.WriteLine(LogLevel.Error, Resource.Error_WatchRegistry, errorCode);
break;
}
- RegChanged?.Invoke(this, null);
+ RegChanged?.Invoke(this, EventArgs.Empty);
}
}
}
@@ -134,7 +133,7 @@ private void Monitor()
}
finally
{
- _stoppedEvent.Dispose();
+ _stoppedEvent?.Dispose();
_stoppedEvent = null;
_section.Dispose();
diff --git a/src/DebugEngineHost/VSFeedbackLogger.cs b/src/DebugEngineHost/VSFeedbackLogger.cs
index 30dd240cb..bb7eb4852 100644
--- a/src/DebugEngineHost/VSFeedbackLogger.cs
+++ b/src/DebugEngineHost/VSFeedbackLogger.cs
@@ -1,11 +1,11 @@
-// Copyright (c) Microsoft. All rights reserved.
+// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using Newtonsoft.Json.Linq;
+using Process = global::System.Diagnostics.Process;
namespace Microsoft.DebugEngineHost
{
@@ -21,10 +21,10 @@ internal class VSFeedbackLogger
private readonly System.DateTime _vsStartTime;
private bool _enabled;
- private readonly FileSystemWatcher _vsFeedbackFileWatcher;
+ private readonly FileSystemWatcher? _vsFeedbackFileWatcher;
private readonly FeedbackLogBuffer _circularBuffer;
- private StreamWriter _logWriter;
+ private StreamWriter? _logWriter;
private readonly object _syncObj = new object();
internal VSFeedbackLogger(FeedbackLogBuffer circularBuffer)
@@ -103,7 +103,7 @@ private void OnFeedbackSemaphoreDeleted(object sender, FileSystemEventArgs e)
_enabled = false;
_circularBuffer.FlushNewEntries();
- if (_logWriter != null)
+ if (_logWriter is not null)
{
_logWriter.Dispose();
_logWriter = null;
@@ -128,8 +128,8 @@ private bool IsLoggingEnabledForThisVSInstance(string semaphoreFilePath)
string content = File.ReadAllText(semaphoreFilePath);
JObject root = JObject.Parse(content);
- JContainer pidCollection = root["processIds"] as JContainer;
- if (pidCollection != null)
+ JContainer? pidCollection = root["processIds"] as JContainer;
+ if (pidCollection is not null)
{
return pidCollection.Values().Contains(_vsPid);
}
diff --git a/src/DebugEngineHost/VSImpl/VSEventCallbackWrapper.cs b/src/DebugEngineHost/VSImpl/VSEventCallbackWrapper.cs
index cd1ded32b..98f7a7535 100644
--- a/src/DebugEngineHost/VSImpl/VSEventCallbackWrapper.cs
+++ b/src/DebugEngineHost/VSImpl/VSEventCallbackWrapper.cs
@@ -1,11 +1,10 @@
-// Copyright (c) Microsoft. All rights reserved.
+// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.VisualStudio.Debugger.Interop;
using Microsoft.VisualStudio.OLE.Interop;
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
@@ -31,7 +30,7 @@ internal class VSEventCallbackWrapper : IDebugEventCallback2
private readonly object _cacheLock = new object();
private int _cachedEventCallbackThread;
- private IDebugEventCallback2 _cacheEventCallback;
+ private IDebugEventCallback2? _cacheEventCallback;
internal VSEventCallbackWrapper(IDebugEventCallback2 ad7Callback)
{
@@ -90,11 +89,11 @@ private IDebugEventCallback2 GetAD7EventCallback()
// We send esentially all events from the same thread, so lets optimize the common case
int currentThreadId = Thread.CurrentThread.ManagedThreadId;
- if (_cacheEventCallback != null && _cachedEventCallbackThread == currentThreadId)
+ if (_cacheEventCallback is not null && _cachedEventCallbackThread == currentThreadId)
{
lock (_cacheLock)
{
- if (_cacheEventCallback != null && _cachedEventCallbackThread == currentThreadId)
+ if (_cacheEventCallback is not null && _cachedEventCallbackThread == currentThreadId)
{
return _cacheEventCallback;
}
diff --git a/src/DebugEngineHost/VSImpl/VsWaitDialog.cs b/src/DebugEngineHost/VSImpl/VsWaitDialog.cs
index 1dc56fcd2..402450ddc 100644
--- a/src/DebugEngineHost/VSImpl/VsWaitDialog.cs
+++ b/src/DebugEngineHost/VSImpl/VsWaitDialog.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft. All rights reserved.
+// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
@@ -11,7 +11,7 @@ namespace Microsoft.DebugEngineHost.VSImpl
{
internal class VSWaitDialog
{
- private readonly IVsThreadedWaitDialog2 _waitDialog;
+ private readonly IVsThreadedWaitDialog2? _waitDialog;
private const int m_delayShowDialogTimeInSeconds = 2;
private bool _started;
private string _format;
@@ -36,7 +36,7 @@ public VSWaitDialog(string format, string caption)
}
public void ShowWaitDialog(string item)
{
- if (_waitDialog == null)
+ if (_waitDialog is null)
{
return;
}
@@ -69,7 +69,7 @@ public void ShowWaitDialog(string item)
public void EndWaitDialog()
{
- if (_waitDialog == null)
+ if (_waitDialog is null)
{
return;
}
diff --git a/src/DebugEngineHost/VSImpl/VsWaitLoop.cs b/src/DebugEngineHost/VSImpl/VsWaitLoop.cs
index 8cba857d5..afd691899 100644
--- a/src/DebugEngineHost/VSImpl/VsWaitLoop.cs
+++ b/src/DebugEngineHost/VSImpl/VsWaitLoop.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft. All rights reserved.
+// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
@@ -11,7 +11,6 @@
using System.Threading;
using Microsoft.Win32.SafeHandles;
using Microsoft.VisualStudio;
-using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Microsoft.DebugEngineHost.VSImpl
@@ -24,7 +23,7 @@ namespace Microsoft.DebugEngineHost.VSImpl
// ************************************************************
internal class VsWaitLoop
{
- private readonly IVsCommonMessagePump _messagePump;
+ private readonly IVsCommonMessagePump? _messagePump;
private VsWaitLoop(string text)
{
@@ -52,10 +51,10 @@ private VsWaitLoop(string text)
_messagePump = messagePump;
}
- static public VsWaitLoop TryCreate(string text)
+ static public VsWaitLoop? TryCreate(string text)
{
VsWaitLoop waitLoop = new VsWaitLoop(text);
- if (waitLoop._messagePump == null)
+ if (waitLoop._messagePump is null)
return null;
return waitLoop;
@@ -71,6 +70,7 @@ static public VsWaitLoop TryCreate(string text)
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Runtime.InteropServices.SafeHandle.DangerousGetHandle")]
public void Wait(WaitHandle launchCompleteHandle, CancellationTokenSource cancellationSource)
{
+ Debug.Assert(_messagePump is not null, "Wait should only be called on instances created via TryCreate that returned non-null");
int hr;
SafeWaitHandle safeWaitHandle = launchCompleteHandle.SafeWaitHandle;
@@ -118,11 +118,13 @@ public void Wait(WaitHandle launchCompleteHandle, CancellationTokenSource cancel
public void SetProgress(int totalSteps, int currentStep, string progressText)
{
+ Debug.Assert(_messagePump is not null, "SetProgress should only be called on a valid VsWaitLoop instance");
_messagePump.SetProgressInfo(totalSteps, currentStep, progressText);
}
public void SetText(string text)
{
+ Debug.Assert(_messagePump is not null, "SetText should only be called on a valid VsWaitLoop instance");
_messagePump.SetWaitText(text);
}
}
diff --git a/src/Shared/NullableAttributes.cs b/src/Shared/NullableAttributes.cs
new file mode 100644
index 000000000..63d4ca7f2
--- /dev/null
+++ b/src/Shared/NullableAttributes.cs
@@ -0,0 +1,150 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// Source:
+
+// This file is a tweaked version of https://github.com/dotnet/runtime/blob/c95aa3f48aa591dca870ee00c31c3d8bdc740b5a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs
+
+#pragma warning disable CA1019 // Define accessors for attribute arguments
+
+// Currently, we always need these definitions, but it can be removed if we ever compile against .NET 5 or newer
+#if !NETCOREAPP
+
+namespace System.Diagnostics.CodeAnalysis
+{
+ /// Specifies that null is allowed as an input even if the corresponding type disallows it.
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
+ internal sealed class AllowNullAttribute : Attribute { }
+
+ /// Specifies that null is disallowed as an input even if the corresponding type allows it.
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
+ internal sealed class DisallowNullAttribute : Attribute { }
+
+ /// Specifies that an output may be null even if the corresponding type disallows it.
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
+ internal sealed class MaybeNullAttribute : Attribute { }
+
+ /// Specifies that an output will not be null even if the corresponding type allows it. Specifies that an input argument was not null when the call returns.
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
+ internal sealed class NotNullAttribute : Attribute { }
+
+ /// Specifies that when a method returns , the parameter may be null even if the corresponding type disallows it.
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ internal sealed class MaybeNullWhenAttribute : Attribute
+ {
+ /// Initializes the attribute with the specified return value condition.
+ ///
+ /// The return value condition. If the method returns this value, the associated parameter may be null.
+ ///
+ public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
+
+ /// Gets the return value condition.
+ public bool ReturnValue { get; }
+ }
+
+ /// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it.
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ internal sealed class NotNullWhenAttribute : Attribute
+ {
+ /// Initializes the attribute with the specified return value condition.
+ ///
+ /// The return value condition. If the method returns this value, the associated parameter will not be null.
+ ///
+ public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
+
+ /// Gets the return value condition.
+ public bool ReturnValue { get; }
+ }
+
+ /// Specifies that the output will be non-null if the named parameter is non-null.
+ [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
+ internal sealed class NotNullIfNotNullAttribute : Attribute
+ {
+ /// Initializes the attribute with the associated parameter name.
+ ///
+ /// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null.
+ ///
+ public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName;
+
+ /// Gets the associated parameter name.
+ public string ParameterName { get; }
+ }
+
+ /// Applied to a method that will never return under any circumstance.
+ [AttributeUsage(AttributeTargets.Method, Inherited = false)]
+ internal sealed class DoesNotReturnAttribute : Attribute { }
+
+ /// Specifies that the method will not return if the associated Boolean parameter is passed the specified value.
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ internal sealed class DoesNotReturnIfAttribute : Attribute
+ {
+ /// Initializes the attribute with the specified parameter value.
+ ///
+ /// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to
+ /// the associated parameter matches this value.
+ ///
+ public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue;
+
+ /// Gets the condition parameter value.
+ public bool ParameterValue { get; }
+ }
+
+ /// Specifies that the method or property will ensure that the listed field and property members have not-null values.
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
+ internal sealed class MemberNotNullAttribute : Attribute
+ {
+ /// Initializes the attribute with a field or property member.
+ ///
+ /// The field or property member that is promised to be not-null.
+ ///
+ public MemberNotNullAttribute(string member) => Members = new[] { member };
+
+ /// Initializes the attribute with the list of field and property members.
+ ///
+ /// The list of field and property members that are promised to be not-null.
+ ///
+ public MemberNotNullAttribute(params string[] members) => Members = members;
+
+ /// Gets field or property member names.
+ public string[] Members { get; }
+ }
+
+ /// Specifies that the method or property will ensure that the listed field and property members have not-null values when returning with the specified return value condition.
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
+ internal sealed class MemberNotNullWhenAttribute : Attribute
+ {
+ /// Initializes the attribute with the specified return value condition and a field or property member.
+ ///
+ /// The return value condition. If the method returns this value, the associated parameter will not be null.
+ ///
+ ///
+ /// The field or property member that is promised to be not-null.
+ ///
+
+ public MemberNotNullWhenAttribute(bool returnValue, string member)
+ {
+ ReturnValue = returnValue;
+ Members = new[] { member };
+ }
+
+ /// Initializes the attribute with the specified return value condition and list of field and property members.
+ ///
+ /// The return value condition. If the method returns this value, the associated parameter will not be null.
+ ///
+ ///
+ /// The list of field and property members that are promised to be not-null.
+ ///
+ public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
+ {
+ ReturnValue = returnValue;
+ Members = members;
+ }
+
+ /// Gets the return value condition.
+ public bool ReturnValue { get; }
+
+ /// Gets field or property member names.
+ public string[] Members { get; }
+ }
+}
+
+#endif
\ No newline at end of file