diff --git a/src/QsCompiler/CompilationManager/ProjectManager.cs b/src/QsCompiler/CompilationManager/ProjectManager.cs index 16bc290cc6..0ad42a3005 100644 --- a/src/QsCompiler/CompilationManager/ProjectManager.cs +++ b/src/QsCompiler/CompilationManager/ProjectManager.cs @@ -738,7 +738,7 @@ public bool ManagerTask(Uri file, Action executeTask, ID /// /// used to log exceptions raised during processing -> may be null! /// - private readonly Action logException; + private readonly Action? logException; /// /// general purpose logging routine used for major loading events -> may be null! @@ -750,7 +750,7 @@ public bool ManagerTask(Uri file, Action executeTask, ID /// that action is called whenever diagnostics for the project have changed and are ready for publishing. /// Any exceptions caught during processing are logged using the given exception logger. /// - public ProjectManager(Action exceptionLogger, Action? log = null, Action? publishDiagnostics = null) + public ProjectManager(Action? exceptionLogger, Action? log = null, Action? publishDiagnostics = null) { this.load = new ProcessingQueue(exceptionLogger); this.projects = new ConcurrentDictionary(); diff --git a/src/QsCompiler/LanguageServer/EditorState.cs b/src/QsCompiler/LanguageServer/EditorState.cs index f9583d0d31..35cbe022d4 100644 --- a/src/QsCompiler/LanguageServer/EditorState.cs +++ b/src/QsCompiler/LanguageServer/EditorState.cs @@ -30,7 +30,7 @@ internal class EditorState : IDisposable private readonly Action publish; private readonly Action, Dictionary> sendTelemetry; - private readonly Action onTemporaryProjectLoaded; + private readonly Action? onTemporaryProjectLoaded; /// /// needed to determine if the reality of a source file that has changed on disk is indeed given by the content on disk, @@ -58,11 +58,11 @@ internal class EditorState : IDisposable /// internal EditorState( ProjectLoader projectLoader, - Action publishDiagnostics, - Action, Dictionary> sendTelemetry, - Action log, - Action onException, - Action onTemporaryProjectLoaded) + Action? publishDiagnostics, + Action, Dictionary>? sendTelemetry, + Action? log, + Action? onException, + Action? onTemporaryProjectLoaded) { this.ignoreEditorUpdatesForFiles = new ConcurrentDictionary(); this.sendTelemetry = sendTelemetry ?? ((eventName, properties, measurements) => { }); @@ -258,7 +258,7 @@ internal Task OpenFileAsync( { var projectUri = this.QsTemporaryProjectLoader(textDocument.Uri, sdkVersion: null); // null means the Sdk version will be set to the extension version this.projects.ProjectChangedOnDiskAsync(projectUri, this.QsProjectLoader, this.GetOpenFile); - this.onTemporaryProjectLoaded(projectUri); + this.onTemporaryProjectLoaded?.Invoke(projectUri); createdTemporaryProject = true; } catch (Exception ex) diff --git a/src/QsCompiler/TestTargets/Simulation/Target/Driver.cs b/src/QsCompiler/TestTargets/Simulation/Target/Driver.cs index 65422a3c9b..1fec88445b 100644 --- a/src/QsCompiler/TestTargets/Simulation/Target/Driver.cs +++ b/src/QsCompiler/TestTargets/Simulation/Target/Driver.cs @@ -32,9 +32,9 @@ static void Main(string[] args) using (var qsim = new QuantumSimulator()) { - Task task = entryPoint.Invoke(null, new[] { qsim }) as Task; + var task = entryPoint.Invoke(null, new[] { qsim }) as Task; task?.Wait(); } } } -} \ No newline at end of file +} diff --git a/src/QsCompiler/TestTargets/Simulation/Target/Program.cs b/src/QsCompiler/TestTargets/Simulation/Target/Program.cs index 2902715bd8..3c13ec56cc 100644 --- a/src/QsCompiler/TestTargets/Simulation/Target/Program.cs +++ b/src/QsCompiler/TestTargets/Simulation/Target/Program.cs @@ -31,7 +31,8 @@ public CsharpGeneration() => public IDictionary AssemblyConstants { get; } /// - public IEnumerable GeneratedDiagnostics { get; private set; } + public IEnumerable GeneratedDiagnostics { get; private set; } = + Enumerable.Empty(); /// public bool ImplementsTransformation => true; diff --git a/src/QsCompiler/TestTargets/Simulation/Target/Simulation.csproj b/src/QsCompiler/TestTargets/Simulation/Target/Simulation.csproj index 179585d9cf..60927301c2 100644 --- a/src/QsCompiler/TestTargets/Simulation/Target/Simulation.csproj +++ b/src/QsCompiler/TestTargets/Simulation/Target/Simulation.csproj @@ -6,6 +6,8 @@ netstandard2.1 x64 true + enable + nullable diff --git a/src/QsCompiler/Tests.DocGenerator/Tests.DocGenerator.csproj b/src/QsCompiler/Tests.DocGenerator/Tests.DocGenerator.csproj index a0328017db..963b1ecbd5 100644 --- a/src/QsCompiler/Tests.DocGenerator/Tests.DocGenerator.csproj +++ b/src/QsCompiler/Tests.DocGenerator/Tests.DocGenerator.csproj @@ -6,6 +6,8 @@ false Microsoft.Quantum.QsCompiler.Documentation.Testing Tests.Microsoft.Quantum.QsDocumentationParser + enable + nullable diff --git a/src/QsCompiler/Tests.LanguageServer/ProjectLoaderTests.cs b/src/QsCompiler/Tests.LanguageServer/ProjectLoaderTests.cs index 54b9cab3de..562030ff8e 100644 --- a/src/QsCompiler/Tests.LanguageServer/ProjectLoaderTests.cs +++ b/src/QsCompiler/Tests.LanguageServer/ProjectLoaderTests.cs @@ -38,7 +38,7 @@ private static string ProjectFileName(string project) => private static string SourceFileName(string project, string fileName) => Path.Combine("TestProjects", project, fileName); - private (string, ProjectInformation) Context(string project) + private (string, ProjectInformation?) Context(string project) { var relativePath = ProjectFileName(project); var uri = new Uri(Path.GetFullPath(relativePath)); @@ -73,18 +73,18 @@ public void SupportedTargetFrameworks() [TestMethod] public void FindProjectTargetFramework() { - void CompareFramework(string project, string expected) + void CompareFramework(string project, string? expected) { var projectFileName = ProjectFileName(project); var props = new ProjectLoader().DesignTimeBuildProperties(projectFileName, out var _, (x, y) => (y.Contains('.') ? 1 : 0) - (x.Contains('.') ? 1 : 0)); - if (!props.TryGetValue("TargetFramework", out string actual)) + if (!props.TryGetValue("TargetFramework", out var actual)) { actual = null; } Assert.AreEqual(expected, actual); } - var testProjects = new (string, string)[] + var testProjects = new (string, string?)[] { ("test1", "netcoreapp2.1"), ("test2", "netstandard2.0"), @@ -129,10 +129,10 @@ public void LoadNonQsharpProjects() public void LoadOutdatedQsharpProject() { var (projectFile, context) = this.Context("test9"); - var projDir = Path.GetDirectoryName(projectFile); + var projDir = Path.GetDirectoryName(projectFile) ?? ""; Assert.IsNotNull(context); - Assert.AreEqual("test9.dll", Path.GetFileName(context.Properties.OutputPath)); - Assert.IsTrue(Path.GetDirectoryName(context.Properties.OutputPath).StartsWith(projDir)); + Assert.AreEqual("test9.dll", Path.GetFileName(context!.Properties.OutputPath)); + Assert.IsTrue((Path.GetDirectoryName(context.Properties.OutputPath) ?? "").StartsWith(projDir)); var qsFiles = new string[] { @@ -149,10 +149,10 @@ public void LoadOutdatedQsharpProject() public void LoadQsharpCoreLibraries() { var (projectFile, context) = this.Context("test3"); - var projDir = Path.GetDirectoryName(projectFile); + var projDir = Path.GetDirectoryName(projectFile) ?? ""; Assert.IsNotNull(context); - Assert.AreEqual("test3.dll", Path.GetFileName(context.Properties.OutputPath)); - Assert.IsTrue(Path.GetDirectoryName(context.Properties.OutputPath).StartsWith(projDir)); + Assert.AreEqual("test3.dll", Path.GetFileName(context!.Properties.OutputPath)); + Assert.IsTrue((Path.GetDirectoryName(context.Properties.OutputPath) ?? "").StartsWith(projDir)); var qsFiles = new string[] { @@ -168,10 +168,10 @@ public void LoadQsharpCoreLibraries() CollectionAssert.AreEquivalent(qsFiles, context.SourceFiles.ToArray()); (projectFile, context) = this.Context("test12"); - projDir = Path.GetDirectoryName(projectFile); + projDir = Path.GetDirectoryName(projectFile) ?? ""; Assert.IsNotNull(context); - Assert.AreEqual("test12.dll", Path.GetFileName(context.Properties.OutputPath)); - Assert.IsTrue(Path.GetDirectoryName(context.Properties.OutputPath).StartsWith(projDir)); + Assert.AreEqual("test12.dll", Path.GetFileName(context!.Properties.OutputPath)); + Assert.IsTrue((Path.GetDirectoryName(context.Properties.OutputPath) ?? "").StartsWith(projDir)); qsFiles = new string[] { @@ -191,10 +191,10 @@ public void LoadQsharpCoreLibraries() public void LoadQsharpFrameworkLibrary() { var (projectFile, context) = this.Context("test7"); - var projDir = Path.GetDirectoryName(projectFile); + var projDir = Path.GetDirectoryName(projectFile) ?? ""; Assert.IsNotNull(context); - Assert.AreEqual("test7.dll", Path.GetFileName(context.Properties.OutputPath)); - Assert.IsTrue(Path.GetDirectoryName(context.Properties.OutputPath).StartsWith(projDir)); + Assert.AreEqual("test7.dll", Path.GetFileName(context!.Properties.OutputPath)); + Assert.IsTrue((Path.GetDirectoryName(context.Properties.OutputPath) ?? "").StartsWith(projDir)); var qsFiles = new string[] { @@ -211,10 +211,10 @@ public void LoadQsharpFrameworkLibrary() public void LoadQsharpConsoleApps() { var (projectFile, context) = this.Context("test4"); - var projDir = Path.GetDirectoryName(projectFile); + var projDir = Path.GetDirectoryName(projectFile) ?? ""; Assert.IsNotNull(context); - Assert.AreEqual("test4.dll", Path.GetFileName(context.Properties.OutputPath)); - Assert.IsTrue(Path.GetDirectoryName(context.Properties.OutputPath).StartsWith(projDir)); + Assert.AreEqual("test4.dll", Path.GetFileName(context!.Properties.OutputPath)); + Assert.IsTrue((Path.GetDirectoryName(context.Properties.OutputPath) ?? "").StartsWith(projDir)); var qsFiles = new string[] { @@ -228,10 +228,10 @@ public void LoadQsharpConsoleApps() CollectionAssert.AreEquivalent(qsFiles, context.SourceFiles.ToArray()); (projectFile, context) = this.Context("test10"); - projDir = Path.GetDirectoryName(projectFile); + projDir = Path.GetDirectoryName(projectFile) ?? ""; Assert.IsNotNull(context); - Assert.AreEqual("test10.dll", Path.GetFileName(context.Properties.OutputPath)); - Assert.IsTrue(Path.GetDirectoryName(context.Properties.OutputPath).StartsWith(projDir)); + Assert.AreEqual("test10.dll", Path.GetFileName(context!.Properties.OutputPath)); + Assert.IsTrue((Path.GetDirectoryName(context.Properties.OutputPath) ?? "").StartsWith(projDir)); qsFiles = new string[] { @@ -243,10 +243,10 @@ public void LoadQsharpConsoleApps() CollectionAssert.AreEquivalent(qsFiles, context.SourceFiles.ToArray()); (projectFile, context) = this.Context("test11"); - projDir = Path.GetDirectoryName(projectFile); + projDir = Path.GetDirectoryName(projectFile) ?? ""; Assert.IsNotNull(context); - Assert.AreEqual("test11.dll", Path.GetFileName(context.Properties.OutputPath)); - Assert.IsTrue(Path.GetDirectoryName(context.Properties.OutputPath).StartsWith(projDir)); + Assert.AreEqual("test11.dll", Path.GetFileName(context!.Properties.OutputPath)); + Assert.IsTrue((Path.GetDirectoryName(context.Properties.OutputPath) ?? "").StartsWith(projDir)); qsFiles = new string[] { @@ -262,10 +262,10 @@ public void LoadQsharpConsoleApps() public void LoadQsharpUnitTest() { var (projectFile, context) = this.Context("test5"); - var projDir = Path.GetDirectoryName(projectFile); + var projDir = Path.GetDirectoryName(projectFile) ?? ""; Assert.IsNotNull(context); - Assert.AreEqual("test5.dll", Path.GetFileName(context.Properties.OutputPath)); - Assert.IsTrue(Path.GetDirectoryName(context.Properties.OutputPath).StartsWith(projDir)); + Assert.AreEqual("test5.dll", Path.GetFileName(context!.Properties.OutputPath)); + Assert.IsTrue((Path.GetDirectoryName(context.Properties.OutputPath) ?? "").StartsWith(projDir)); var qsFiles = new string[] { @@ -286,10 +286,10 @@ public void LoadQsharpUnitTest() public void LoadQsharpMultiFrameworkLibrary() { var (projectFile, context) = this.Context("test6"); - var projDir = Path.GetDirectoryName(projectFile); + var projDir = Path.GetDirectoryName(projectFile) ?? ""; Assert.IsNotNull(context); - Assert.AreEqual("test6.dll", Path.GetFileName(context.Properties.OutputPath)); - Assert.IsTrue(Path.GetDirectoryName(context.Properties.OutputPath).StartsWith(projDir)); + Assert.AreEqual("test6.dll", Path.GetFileName(context!.Properties.OutputPath)); + Assert.IsTrue((Path.GetDirectoryName(context.Properties.OutputPath) ?? "").StartsWith(projDir)); var qsFiles = new string[] { @@ -314,8 +314,9 @@ public void LoadQsharpTemporaryProject() var qsFiles = new string[] { sourceFile }; var projectInformation = CompilationContext.Load(projectUri); - Assert.IsTrue(projectInformation.UsesCanon()); - CollectionAssert.AreEquivalent(qsFiles, projectInformation.SourceFiles.ToArray()); + Assert.IsNotNull(projectInformation); + Assert.IsTrue(projectInformation!.UsesCanon()); + CollectionAssert.AreEquivalent(qsFiles, projectInformation!.SourceFiles.ToArray()); } } @@ -324,7 +325,7 @@ internal static class CompilationContext private static void LogOutput(string msg, MessageType level) => Console.WriteLine($"[{level}]: {msg}"); - internal static ProjectInformation Load(Uri projectFile) => + internal static ProjectInformation? Load(Uri projectFile) => new EditorState(new ProjectLoader(LogOutput), null, null, null, null, null) .QsProjectLoader(projectFile, out var loaded) ? loaded : null; diff --git a/src/QsCompiler/Tests.LanguageServer/TestSetup.cs b/src/QsCompiler/Tests.LanguageServer/TestSetup.cs index 82fb6912d6..4ee4cbd245 100644 --- a/src/QsCompiler/Tests.LanguageServer/TestSetup.cs +++ b/src/QsCompiler/Tests.LanguageServer/TestSetup.cs @@ -18,8 +18,8 @@ public sealed partial class BasicFunctionality : IDisposable { // basic setup - private Connection connection; - private JsonRpc rpc; + private Connection? connection; + private JsonRpc rpc = null!; // Initialized in SetupServerConnectionAsync. private readonly RandomInput inputGenerator = new RandomInput(); private readonly Stack receivedDiagnostics = new Stack(); @@ -28,7 +28,7 @@ public Task GetFileContentInMemoryAsync(string filename) => Methods.WorkspaceExecuteCommand.Name, TestUtils.ServerCommand(CommandIds.FileContentInMemory, TestUtils.GetTextDocumentIdentifier(filename))); - public Task GetFileDiagnosticsAsync(string filename = null) => + public Task GetFileDiagnosticsAsync(string? filename = null) => this.rpc.InvokeWithParameterObjectAsync( Methods.WorkspaceExecuteCommand.Name, TestUtils.ServerCommand(CommandIds.FileDiagnostics, filename == null ? new TextDocumentIdentifier { Uri = null } : TestUtils.GetTextDocumentIdentifier(filename))); diff --git a/src/QsCompiler/Tests.LanguageServer/TestUtils.cs b/src/QsCompiler/Tests.LanguageServer/TestUtils.cs index 9f0443f69f..3c8163e905 100644 --- a/src/QsCompiler/Tests.LanguageServer/TestUtils.cs +++ b/src/QsCompiler/Tests.LanguageServer/TestUtils.cs @@ -107,16 +107,12 @@ internal static int GetRangeLength(VisualStudio.LanguageServer.Protocol.Range ra internal static void ApplyEdit(TextDocumentContentChangeEvent change, ref List content) { - if (content == null) - { - throw new ArgumentNullException(nameof(content)); - } if (!content.Any()) { throw new ArgumentException("the given content has to have at least on line"); } - Assert.IsTrue(IsValidRange(change?.Range) && change.Text != null); + Assert.IsTrue(IsValidRange(change.Range) && change.Text != null); Assert.IsTrue(change.Range.End.Line < content.Count()); Assert.IsTrue(change.Range.Start.Character <= content[change.Range.Start.Line].Length); Assert.IsTrue(change.Range.End.Character <= content[change.Range.End.Line].Length); @@ -143,7 +139,7 @@ internal static void ApplyEdit(TextDocumentContentChangeEvent change, ref List position.Line >= 0 && position.Character >= 0; diff --git a/src/QsCompiler/Tests.LanguageServer/Tests.LanguageServer.csproj b/src/QsCompiler/Tests.LanguageServer/Tests.LanguageServer.csproj index b0c6a44f06..16cfc61b0f 100644 --- a/src/QsCompiler/Tests.LanguageServer/Tests.LanguageServer.csproj +++ b/src/QsCompiler/Tests.LanguageServer/Tests.LanguageServer.csproj @@ -8,6 +8,8 @@ x64 Library NU1701 + enable + nullable diff --git a/src/QsCompiler/Tests.LanguageServer/Tests.cs b/src/QsCompiler/Tests.LanguageServer/Tests.cs index 7cfe8f2577..b5644cd652 100644 --- a/src/QsCompiler/Tests.LanguageServer/Tests.cs +++ b/src/QsCompiler/Tests.LanguageServer/Tests.cs @@ -81,9 +81,9 @@ public async Task ServerCapabilitiesAsync() Assert.IsNotNull(initReply.Capabilities.CompletionProvider.TriggerCharacters); Assert.IsTrue(initReply.Capabilities.CompletionProvider.TriggerCharacters.SequenceEqual(new[] { ".", "(" })); Assert.IsNotNull(initReply.Capabilities.SignatureHelpProvider?.TriggerCharacters); - Assert.IsTrue(initReply.Capabilities.SignatureHelpProvider.TriggerCharacters.Any()); + Assert.IsTrue(initReply.Capabilities.SignatureHelpProvider!.TriggerCharacters.Any()); Assert.IsNotNull(initReply.Capabilities.ExecuteCommandProvider?.Commands); - Assert.IsNotNull(initReply.Capabilities.ExecuteCommandProvider.Commands.Contains(CommandIds.ApplyEdit)); + Assert.IsTrue(initReply.Capabilities.ExecuteCommandProvider!.Commands.Contains(CommandIds.ApplyEdit)); Assert.IsTrue(initReply.Capabilities.TextDocumentSync.OpenClose); Assert.IsTrue(initReply.Capabilities.TextDocumentSync.Save.IncludeText); Assert.AreEqual(TextDocumentSyncKind.Incremental, initReply.Capabilities.TextDocumentSync.Change);