diff --git a/src/QsCompiler/CommandLineTool/Commands/Build.cs b/src/QsCompiler/CommandLineTool/Commands/Build.cs index ef31dbef64..c9eccd34a7 100644 --- a/src/QsCompiler/CommandLineTool/Commands/Build.cs +++ b/src/QsCompiler/CommandLineTool/Commands/Build.cs @@ -152,14 +152,9 @@ private static IEnumerable SplitCommandLineArguments(string commandLine) /// /// Reads the content off all given response files and tries to parse their concatenated content as command line arguments. /// Logs a suitable exceptions and returns null if the parsing fails. - /// Throws an ArgumentNullException if the given sequence of responseFiles is null. /// private static BuildOptions? FromResponseFiles(IEnumerable responseFiles) { - if (responseFiles == null) - { - throw new ArgumentNullException(nameof(responseFiles)); - } var commandLine = string.Join(" ", responseFiles.Select(File.ReadAllText)); var args = SplitCommandLineArguments(commandLine); var parsed = Parser.Default.ParseArguments(args); @@ -177,18 +172,9 @@ private static IEnumerable SplitCommandLineArguments(string commandLine) /// /// Builds the compilation for the Q# code or Q# snippet and referenced assemblies defined by the given options. /// Returns a suitable error code if one of the compilation or generation steps fails. - /// Throws an ArgumentNullException if any of the given arguments is null. /// public static int Run(BuildOptions options, ConsoleLogger logger) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - if (logger == null) - { - throw new ArgumentNullException(nameof(logger)); - } if (!BuildOptions.IncorporateResponseFiles(options, out var incorporated)) { logger.Log(ErrorCode.InvalidCommandLineArgsInResponseFiles, Array.Empty()); diff --git a/src/QsCompiler/CommandLineTool/Commands/Diagnose.cs b/src/QsCompiler/CommandLineTool/Commands/Diagnose.cs index 14fc8486bc..ddc876f371 100644 --- a/src/QsCompiler/CommandLineTool/Commands/Diagnose.cs +++ b/src/QsCompiler/CommandLineTool/Commands/Diagnose.cs @@ -78,14 +78,9 @@ public static IEnumerable UsageExamples /// Logs the content of each file in the given compilation as Information using the given logger. /// If the id of a file is consistent with the one assigned to a code snippet, /// strips the lines of code that correspond to the wrapping defined by WrapSnippet. - /// Throws an ArgumentNullException if the given compilation is null. /// private static void PrintFileContentInMemory(Compilation compilation, ILogger logger) { - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } foreach (var file in compilation.SourceFiles) { IEnumerable inMemory = compilation.FileContent[file]; @@ -110,14 +105,9 @@ private static void PrintFileContentInMemory(Compilation compilation, ILogger lo /// Logs the tokenization of each file in the given compilation as Information using the given logger. /// If the id of a file is consistent with the one assigned to a code snippet, /// strips the tokens that correspond to the wrapping defined by WrapSnippet. - /// Throws an ArgumentNullException if the given compilation is null. /// private static void PrintContentTokenization(Compilation compilation, ILogger logger) { - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } foreach (var file in compilation.SourceFiles) { var tokenization = compilation.Tokenization[file].Select(tokens => tokens.Select(token => token.Kind)); @@ -152,14 +142,9 @@ private static void PrintContentTokenization(Compilation compilation, ILogger lo /// If the id of a file is consistent with the one assigned to a code snippet, /// strips the lines of code that correspond to the wrapping defined by WrapSnippet. /// Throws an ArgumentException if this is not possible because the given syntax tree is inconsistent with that wrapping. - /// Throws an ArgumentNullException if the given compilation is null. /// private static void PrintSyntaxTree(IEnumerable? evaluatedTree, Compilation compilation, ILogger logger) { - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } evaluatedTree ??= compilation.SyntaxTree.Values; foreach (var file in compilation.SourceFiles) @@ -191,14 +176,9 @@ void PrintTree(string serialization) => logger.Log( /// If the id of a file is consistent with the one assigned to a code snippet, /// strips the lines of code that correspond to the wrapping defined by WrapSnippet. /// Throws an ArgumentException if this is not possible because the given syntax tree is inconsistent with that wrapping. - /// Throws an ArgumentNullException if the given compilation is null. /// private static void PrintGeneratedQs(IEnumerable? evaluatedTree, Compilation compilation, ILogger logger) { - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } evaluatedTree ??= compilation.SyntaxTree.Values; foreach (var file in compilation.SourceFiles) @@ -224,14 +204,9 @@ private static void PrintGeneratedQs(IEnumerable? evaluatedTree, Co /// /// Strips the namespace and callable declaration that is consistent with the wrapping defined by WrapSnippet. /// Throws an ArgumentException if this is not possible because the given syntax tree is inconsistent with that wrapping. - /// Throws an ArgumentNullException if the given syntaxTree is null. /// public static IEnumerable StripSnippetWrapping(IEnumerable syntaxTree) { - if (syntaxTree == null) - { - throw new ArgumentNullException(nameof(syntaxTree)); - } var incorrectWrapperException = new ArgumentException("syntax tree does not reflect the expected wrapper"); if (syntaxTree.Count() != 1 || syntaxTree.Single().Elements.Count() != 1) { @@ -253,19 +228,9 @@ public static IEnumerable StripSnippetWrapping(IEnumerable public static int Run(DiagnoseOptions options, ConsoleLogger logger) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - if (logger == null) - { - throw new ArgumentNullException(nameof(logger)); - } - if (!options.ParseAssemblyProperties(out var assemblyConstants)) { logger.Log(WarningCode.InvalidAssemblyProperties, Array.Empty()); diff --git a/src/QsCompiler/CommandLineTool/Commands/Format.cs b/src/QsCompiler/CommandLineTool/Commands/Format.cs index 7a77aa2bf4..be5beeea4d 100644 --- a/src/QsCompiler/CommandLineTool/Commands/Format.cs +++ b/src/QsCompiler/CommandLineTool/Commands/Format.cs @@ -71,14 +71,9 @@ public static string UpdateArrayLiterals(string fileContent) /// If the id of a file is consistent with the one assigned to a code snippet, /// strips the lines of code that correspond to the wrapping defined by WrapSnippet. /// Throws an ArgumentException if this is not possible because the given syntax tree is inconsistent with that wrapping. - /// Throws an ArgumentNullException if the given compilation is null. /// private static IEnumerable GenerateQsCode(Compilation compilation, NonNullable file, ILogger logger) { - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } if (Options.IsCodeSnippet(file)) { var subtree = compilation.SyntaxTree.Values.Select(ns => FilterBySourceFile.Apply(ns, file)).Where(ns => ns.Elements.Any()); @@ -119,15 +114,9 @@ string FormatComments(IEnumerable comments) => /// logs the generated code using the given logger. /// Creates a file containing the generated code in the given output folder otherwise. /// Returns true if the generation succeeded, and false if an exception was thrown. - /// Throws an ArgumentNullException if the given compilation, the file uri or its absolute path are null. /// private static bool GenerateFormattedQsFile(Compilation compilation, NonNullable fileName, string? outputFolder, ILogger logger) { - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - var code = Enumerable.Empty(); try { @@ -158,19 +147,9 @@ private static bool GenerateFormattedQsFile(Compilation compilation, NonNullable /// Generates formatted Q# code for each source file in the compilation. /// Returns a suitable error code if some of the source files or references could not be found or loaded, or if the Q# generation failed. /// Compilation errors are not reflected in the return code, but are logged using the given logger. - /// Throws an ArgumentNullException if any of the given arguments is null. /// public static int Run(FormatOptions options, ConsoleLogger logger) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - if (logger == null) - { - throw new ArgumentNullException(nameof(logger)); - } - ImmutableDictionary LoadSources(SourceFileLoader loadFromDisk) => options.LoadSourcesOrSnippet(logger)(loadFromDisk) .ToImmutableDictionary(entry => entry.Key, entry => UpdateArrayLiterals(entry.Value)); // manually replace array literals diff --git a/src/QsCompiler/CommandLineTool/LoadContext.cs b/src/QsCompiler/CommandLineTool/LoadContext.cs index 4b96832cf5..89409e5e67 100644 --- a/src/QsCompiler/CommandLineTool/LoadContext.cs +++ b/src/QsCompiler/CommandLineTool/LoadContext.cs @@ -39,7 +39,7 @@ public void RemoveFromPath(params string[] paths) => private LoadContext(string parentAssembly) { - this.PathToParentAssembly = parentAssembly ?? throw new ArgumentNullException(nameof(parentAssembly)); + this.PathToParentAssembly = parentAssembly; this.resolver = new AssemblyDependencyResolver(this.PathToParentAssembly); this.fallbackPaths = new HashSet(); this.Resolving += this.OnResolving; diff --git a/src/QsCompiler/CommandLineTool/Logging.cs b/src/QsCompiler/CommandLineTool/Logging.cs index c5fde620ce..1efd361a47 100644 --- a/src/QsCompiler/CommandLineTool/Logging.cs +++ b/src/QsCompiler/CommandLineTool/Logging.cs @@ -40,14 +40,9 @@ public ConsoleLogger( /// /// Prints the given message to the Console. /// Errors and Warnings are printed to the error stream. - /// Throws an ArgumentNullException if the given message is null. /// private static void PrintToConsole(DiagnosticSeverity severity, string message) { - if (message == null) - { - throw new ArgumentNullException(nameof(message)); - } var (stream, color) = severity == DiagnosticSeverity.Error ? (Console.Error, ConsoleColor.Red) : severity == DiagnosticSeverity.Warning ? (Console.Error, ConsoleColor.Yellow) : diff --git a/src/QsCompiler/CompilationManager/AssemblyLoader.cs b/src/QsCompiler/CompilationManager/AssemblyLoader.cs index 167509b27b..5e74d2c13f 100644 --- a/src/QsCompiler/CompilationManager/AssemblyLoader.cs +++ b/src/QsCompiler/CompilationManager/AssemblyLoader.cs @@ -31,19 +31,16 @@ public static class AssemblyLoader /// Returns false if some of the content could not be loaded successfully, /// possibly because the referenced assembly has been compiled with an older compiler version. /// If onDeserializationException is specified, invokes the given action on any exception thrown during deserialization. - /// Throws an ArgumentNullException if the given uri is null. + /// Throws an ArgumentException if the URI is not an absolute file URI. /// Throws a FileNotFoundException if no file with the given name exists. /// Throws the corresponding exceptions if the information cannot be extracted. /// public static bool LoadReferencedAssembly(Uri asm, out References.Headers headers, bool ignoreDllResources = false, Action? onDeserializationException = null) { - if (asm == null) + var id = CompilationUnitManager.GetFileId(asm); + if (!File.Exists(asm.LocalPath)) { - throw new ArgumentNullException(nameof(asm)); - } - if (!CompilationUnitManager.TryGetFileId(asm, out var id) || !File.Exists(asm.LocalPath)) - { - throw new FileNotFoundException($"The uri '{asm}' given to the assembly loader is invalid or the file does not exist."); + throw new FileNotFoundException($"The file '{asm.LocalPath}' given to the assembly loader does not exist."); } using var stream = File.OpenRead(asm.LocalPath); @@ -65,7 +62,6 @@ public static bool LoadReferencedAssembly(Uri asm, out References.Headers header /// possibly because the referenced assembly has been compiled with an older compiler version. /// Catches any exception throw upon loading the compilation, and invokes onException with it if such an action has been specified. /// Sets the out parameter to null if an exception occurred during loading. - /// Throws an ArgumentNullException if the given uri is null. /// Throws a FileNotFoundException if no file with the given name exists. /// public static bool LoadReferencedAssembly( @@ -73,10 +69,6 @@ public static bool LoadReferencedAssembly( [NotNullWhen(true)] out QsCompilation? compilation, Action? onException = null) { - if (asmPath == null) - { - throw new ArgumentNullException(nameof(asmPath)); - } if (!File.Exists(asmPath)) { throw new FileNotFoundException($"The file '{asmPath}' does not exist."); @@ -102,17 +94,12 @@ public static bool LoadReferencedAssembly( /// Given a stream containing the binary representation of compiled Q# code, returns the corresponding Q# compilation. /// Returns true if the compilation could be deserialized without throwing an exception, and false otherwise. /// If onDeserializationException is specified, invokes the given action on any exception thrown during deserialization. - /// Throws an ArgumentNullException if the given stream is null, but ignores exceptions thrown during deserialization. /// public static bool LoadSyntaxTree( Stream stream, [NotNullWhen(true)] out QsCompilation? compilation, Action? onDeserializationException = null) { - if (stream == null) - { - throw new ArgumentNullException(nameof(stream)); - } using var reader = new BsonDataReader(stream); (compilation, reader.ReadRootValueAsArray) = (null, false); try @@ -141,7 +128,6 @@ private static ImmutableDictionary Resources(this Meta /// Given a reader for the byte stream of a dotnet dll, loads any Q# compilation included as a resource. /// Returns true as well as the loaded compilation if the given dll includes a suitable resource, and returns false otherwise. /// If onDeserializationException is specified, invokes the given action on any exception thrown during deserialization. - /// Throws an ArgumentNullException if any of the given readers is null. /// May throw an exception if the given binary file has been compiled with a different compiler version. /// private static bool FromResource( @@ -149,10 +135,6 @@ private static bool FromResource( [NotNullWhen(true)] out QsCompilation? compilation, Action? onDeserializationException = null) { - if (assemblyFile == null) - { - throw new ArgumentNullException(nameof(assemblyFile)); - } var metadataReader = assemblyFile.GetMetadataReader(); compilation = null; @@ -239,15 +221,10 @@ private static (string, string)? GetAttribute(MetadataReader metadataReader, Cus /// Given a reader for the byte stream of a dotnet dll, read its custom attributes and /// returns a tuple containing the name of the attribute and the constructor argument /// for all attributes defined in a Microsoft.Quantum* namespace. - /// Throws an ArgumentNullException if the given stream is null. /// Throws the corresponding exceptions if the information cannot be extracted. /// private static IEnumerable<(string, string)> LoadHeaderAttributes(PEReader assemblyFile) { - if (assemblyFile == null) - { - throw new ArgumentNullException(nameof(assemblyFile)); - } var metadataReader = assemblyFile.GetMetadataReader(); return metadataReader.GetAssemblyDefinition().GetCustomAttributes() .Select(metadataReader.GetCustomAttribute) diff --git a/src/QsCompiler/CompilationManager/CompilationUnit.cs b/src/QsCompiler/CompilationManager/CompilationUnit.cs index 59c5f160b3..3b508e0758 100644 --- a/src/QsCompiler/CompilationManager/CompilationUnit.cs +++ b/src/QsCompiler/CompilationManager/CompilationUnit.cs @@ -166,15 +166,10 @@ static QsDeclarationAttribute Renamed(QsQualifiedName originalName, Position dec /// Combines the current references with the given references, and verifies that there are no conflicts. /// Calls the given Action onError with suitable diagnostics if two or more references conflict, /// i.e. if two or more references contain a declaration with the same fully qualified name. - /// Throws an ArgumentNullException if the given dictionary of references is null. /// Throws an ArgumentException if the given set shares references with the current one. /// internal References CombineWith(References other, Action? onError = null) { - if (other == null) - { - throw new ArgumentNullException(nameof(other)); - } if (this.Declarations.Keys.Intersect(other.Declarations.Keys).Any()) { throw new ArgumentException("common references exist"); @@ -187,7 +182,6 @@ internal References CombineWith(References other, Action? o /// Verifies that there are no conflicts for the new set of references. /// Calls the given Action onError with suitable diagnostics if two or more references conflict, /// i.e. if two or more references contain a declaration with the same fully qualified name. - /// Throws an ArgumentNullException if the given diagnostics are null. /// internal References Remove(NonNullable source, Action? onError = null) => new References(this.Declarations.Remove(source), onError: onError); @@ -199,11 +193,10 @@ internal References Remove(NonNullable source, Action public References(ImmutableDictionary, Headers> refs, bool loadTestNames = false, Action? onError = null) { - this.Declarations = refs ?? throw new ArgumentNullException(nameof(refs)); + this.Declarations = refs; if (loadTestNames) { this.Declarations = this.Declarations @@ -312,7 +305,6 @@ public void Dispose() /// /// Returns a new CompilationUnit to store and update a compilation referencing the given content (if any), /// with the given sequence of locks registered as dependent locks if the sequence is not null. - /// Throws an ArgumentNullException if any of the given locks is. /// internal CompilationUnit( RuntimeCapabilities capabilities, @@ -326,10 +318,6 @@ internal CompilationUnit( this.syncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); this.dependentLocks = new HashSet(dependentLocks); - if (dependentLocks.Contains(null!)) - { - throw new ArgumentNullException(nameof(dependentLocks), "one or more of the given locks is null"); - } this.RuntimeCapabilities = capabilities; this.IsExecutable = isExecutable; @@ -355,14 +343,13 @@ internal CompilationUnit( /// /// Replaces the GlobalSymbols to match the newly specified references. - /// Throws an ArgumentNullException if the given references are null. /// internal void UpdateReferences(References externals) { this.EnterWriteLock(); try { - this.Externals = externals ?? throw new ArgumentNullException(nameof(externals)); + this.Externals = externals; this.GlobalSymbols = this.CreateGlobalSymbols(); } finally @@ -375,15 +362,10 @@ internal void UpdateReferences(References externals) /// Registers the given lock as a dependent lock - /// i.e. whenever both this compilation unit and a dependent lock are required, /// ensures that the compilation unit has to be the outer lock. - /// Throws an ArgumentNullException if the given lock is null. /// internal void RegisterDependentLock(ReaderWriterLockSlim depLock) { #if DEBUG - if (depLock == null) - { - throw new ArgumentNullException(nameof(depLock)); - } this.syncRoot.EnterWriteLock(); try { @@ -402,15 +384,10 @@ internal void RegisterDependentLock(ReaderWriterLockSlim depLock) /// /// Removes the given lock from the set of dependent locks. /// Returns true if the lock was successfully removed and false otherwise. - /// Throws an ArgumentNullException if the given lock is null. /// internal void UnregisterDependentLock(ReaderWriterLockSlim depLock) { #if DEBUG - if (depLock == null) - { - throw new ArgumentNullException(nameof(depLock)); - } this.syncRoot.EnterWriteLock(); try { @@ -529,19 +506,15 @@ internal IReadOnlyDictionary GetTypes() /// /// If the given updates are not null, replaces the contained types in the compilation, or adds them if they do not yet exist. /// Proceeds to remove any types that are not currently listed in GlobalSymbols from the compilation, and updates all position information. - /// Throws an ArgumentNullException if any of the given types to update is null. /// internal void UpdateTypes(IEnumerable updates) { this.syncRoot.EnterWriteLock(); try { - if (updates != null) + foreach (var t in updates) { - foreach (var t in updates) - { - this.compiledTypes[t.FullName] = t ?? throw new ArgumentNullException(nameof(updates), "the given compiled type is null"); - } + this.compiledTypes[t.FullName] = t; } // remove all types that are no listed in GlobalSymbols @@ -593,19 +566,14 @@ internal void UpdateTypes(IEnumerable updates) /// If the given updates are not null, replaces the contained callables in the compilation, or adds them if they do not yet exist. /// Proceeds to remove any callables and specializations that are not currently listed in GlobalSymbols from the compilation, /// and updates the position information for all callables and specializations. - /// Throws an ArgumentNullException if any of the given callables to update is null. /// internal void UpdateCallables(IEnumerable updates) { this.syncRoot.EnterWriteLock(); try { - foreach (var c in updates ?? Array.Empty()) + foreach (var c in updates) { - if (c?.Specializations == null || c.Specializations.Contains(null)) - { - throw new ArgumentNullException(nameof(updates), "the given compiled callable or specialization is null"); - } this.compiledCallables[c.FullName] = c; } @@ -718,15 +686,10 @@ internal void UpdateCallables(IEnumerable updates) /// Constructs a suitable callable for a given callable declaration header - /// i.e. given all information about a callable except the implementation of its specializations, /// constructs a QsCallable with the implementation of each specialization set to External. - /// Throws an ArgumentNullException if the given header is null. /// private QsCallable GetImportedCallable(CallableDeclarationHeader header) { // TODO: this needs to be adapted if we want to support external specializations - if (header == null) - { - throw new ArgumentNullException(nameof(header)); - } if (Namespace.IsDeclarationAccessible(false, header.Modifiers.Access)) { var definedSpecs = this.GlobalSymbols.DefinedSpecializations(header.QualifiedName); @@ -778,15 +741,9 @@ private QsCallable GetImportedCallable(CallableDeclarationHeader header) /// /// Constructs a suitable type for a given type declaration header. - /// Throws an ArgumentNullException if the given header is null. /// - private QsCustomType GetImportedType(TypeDeclarationHeader header) - { - if (header == null) - { - throw new ArgumentNullException(nameof(header)); - } - return new QsCustomType( + private QsCustomType GetImportedType(TypeDeclarationHeader header) => + new QsCustomType( header.QualifiedName, header.Attributes, header.Modifiers, @@ -796,27 +753,17 @@ private QsCustomType GetImportedType(TypeDeclarationHeader header) header.TypeItems, header.Documentation, QsComments.Empty); - } /// /// Builds a syntax tree containing the given callables and types, /// and attaches the documentation specified by the given dictionary - if any - to each namespace. /// All elements within a namespace will be sorted in alphabetical order. - /// Throws an ArgumentNullException if the given callables or types are null. /// public static ImmutableArray NewSyntaxTree( IEnumerable callables, IEnumerable types, IReadOnlyDictionary, ILookup, ImmutableArray>>? documentation = null) { - if (callables == null) - { - throw new ArgumentNullException(nameof(callables)); - } - if (types == null) - { - throw new ArgumentNullException(nameof(types)); - } var emptyLookup = Array.Empty>().ToLookup(ns => ns, _ => ImmutableArray.Empty); static string QualifiedName(QsQualifiedName fullName) => $"{fullName.Namespace.Value}.{fullName.Name.Value}"; @@ -1036,22 +983,12 @@ internal LocalDeclarations TryGetLocalDeclarations(FileContentManager file, Posi /// If specified, only types and callables from a source for which /// this function returns true are renamed. /// The renamed and updated callables and types. - /// Thrown when the given callables or types are null. internal static (IEnumerable, IEnumerable) RenameInternalDeclarations( IEnumerable callables, IEnumerable types, int additionalAssemblies = 0, Func, bool>? predicate = null) { - if (callables == null) - { - throw new ArgumentNullException(nameof(callables)); - } - if (types == null) - { - throw new ArgumentNullException(nameof(types)); - } - // Assign a unique ID to each reference. NameDecorator decorator = new NameDecorator($"QsRef"); diff --git a/src/QsCompiler/CompilationManager/CompilationUnitManager.cs b/src/QsCompiler/CompilationManager/CompilationUnitManager.cs index 0ceab09881..ca3e11545f 100644 --- a/src/QsCompiler/CompilationManager/CompilationUnitManager.cs +++ b/src/QsCompiler/CompilationManager/CompilationUnitManager.cs @@ -151,14 +151,15 @@ public void Dispose() /// /// Converts a URI into the file ID used during compilation if the URI is an absolute file URI. /// - /// Thrown if the URI is null. - /// Thrown if the URI is not an absolute URI or not a file URI. - public static NonNullable GetFileId(Uri uri) => - uri is null - ? throw new ArgumentNullException(nameof(uri)) - : TryGetFileId(uri, out var fileId) - ? fileId - : throw new ArgumentException("The URI is not an absolute file URI.", nameof(uri)); + /// Thrown if the URI is not an absolute file URI. + public static NonNullable GetFileId(Uri uri) + { + if (!uri.IsAbsoluteUri || !uri.IsFile) + { + throw new ArgumentException("The URI is not an absolute file URI.", nameof(uri)); + } + return NonNullable.New(uri.LocalPath); + } /// /// Converts a URI into the file ID used during compilation if the URI is an absolute file URI. @@ -190,14 +191,9 @@ public static bool TryGetUri(NonNullable fileId, out Uri uri) => /// Subscribes to diagnostics updated events, /// to events indicating when queued changes in the file content manager have not yet been processed, /// and to events indicating that the compilation unit wide semantic verification needs to be updated. - /// Throws an ArgumentNullException if the given file is null. /// private void SubscribeToFileManagerEvents(FileContentManager file) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } file.TimerTriggeredUpdateEvent += this.TriggerFileUpdateAsync; if (this.EnableVerification) { @@ -207,14 +203,9 @@ private void SubscribeToFileManagerEvents(FileContentManager file) /// /// Unsubscribes from all events that SubscribeToFileManagerEvents subscribes to for the given file. - /// Throws an ArgumentNullException if the given file is null. /// private void UnsubscribeFromFileManagerEvents(FileContentManager file) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } file.TimerTriggeredUpdateEvent -= this.TriggerFileUpdateAsync; if (this.EnableVerification) { @@ -225,8 +216,7 @@ private void UnsubscribeFromFileManagerEvents(FileContentManager file) /// /// Initializes a FileContentManager for the given document with the given content. /// If an Action for publishing is given, publishes the diagnostics generated upon processing the given content. - /// Throws an ArgumentNullException if the given file content is null. - /// Throws an ArgumentException if the uri of the given text document identifier is null or not an absolute file uri. + /// Throws an ArgumentException if the uri of the given text document identifier is not an absolute file uri. /// public static FileContentManager InitializeFileManager( Uri uri, @@ -234,16 +224,7 @@ public static FileContentManager InitializeFileManager( Action? publishDiagnostics = null, Action? onException = null) { - if (!TryGetFileId(uri, out NonNullable docKey)) - { - throw new ArgumentException("invalid TextDocumentIdentifier"); - } - if (fileContent == null) - { - throw new ArgumentNullException(nameof(fileContent)); - } - - var file = new FileContentManager(uri, docKey); + var file = new FileContentManager(uri, GetFileId(uri)); try { file.ReplaceFileContent(fileContent); @@ -259,27 +240,17 @@ public static FileContentManager InitializeFileManager( /// /// Initializes a FileContentManager for each entry in the given dictionary of source files and their content. /// If an Action for publishing is given, publishes the diagnostics generated upon content processing. - /// Throws an ArgumentNullException if the given dictionary of files and their content is null. - /// Throws an ArgumentException if any of the given uris is null or not an absolute file uri, or if any of the content is null. + /// Throws an ArgumentException if any of the given uris is not an absolute file uri. /// public static ImmutableHashSet InitializeFileManagers( IDictionary files, Action? publishDiagnostics = null, Action? onException = null) { - if (files == null) - { - throw new ArgumentNullException(nameof(files)); - } - if (files.Any(item => item.Value == null)) - { - throw new ArgumentException("file content cannot be null"); - } - if (files.Any(item => !TryGetFileId(item.Key, out NonNullable docKey))) + if (files.Any(item => !item.Key.IsAbsoluteUri || !item.Key.IsFile)) { throw new ArgumentException("invalid TextDocumentIdentifier"); } - return files.AsParallel() .WithDegreeOfParallelism(Environment.ProcessorCount > 1 ? Environment.ProcessorCount - 1 : Environment.ProcessorCount) .WithExecutionMode(ParallelExecutionMode.ForceParallelism) // we are fine with a slower performance if the work is trivial @@ -292,16 +263,9 @@ public static ImmutableHashSet InitializeFileManagers( /// If a file with that Uri is already listed as source file, /// replaces the current FileContentManager for that file with the given one. /// If the content to update is specified and not null, replaces the tracked content in the file manager with the given one. - /// Throws an ArgumentNullException if any of the compulsory arguments is null or the set uri is. - /// Throws an ArgumentException if the uri of the given text document identifier is null or not an absolute file uri. /// - public Task AddOrUpdateSourceFileAsync(FileContentManager file, string? updatedContent = null) - { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - return this.Processing.QueueForExecutionAsync(() => + public Task AddOrUpdateSourceFileAsync(FileContentManager file, string? updatedContent = null) => + this.Processing.QueueForExecutionAsync(() => { this.compilationUnit.RegisterDependentLock(file.SyncRoot); this.SubscribeToFileManagerEvents(file); @@ -317,23 +281,15 @@ public Task AddOrUpdateSourceFileAsync(FileContentManager file, string? updatedC } this.PublishDiagnostics(file.Diagnostics()); }); - } /// /// Adds the given source files to this compilation unit, adapting the diagnostics for all remaining files as needed. /// If a file with the same Uri is already listed as source file, /// replaces the current FileContentManager for that file with a new one and initialized its content to the given one. /// Spawns a compilation unit wide type checking unless suppressVerification is set to true, even if no files have been added. - /// Throws an ArgumentNullException if the given source files are null. - /// Throws an ArgumentException if an uri is not a valid absolute file uri, or if the content for a file is null. /// - public Task AddOrUpdateSourceFilesAsync(ImmutableHashSet files, bool suppressVerification = false) - { - if (files == null || files.Contains(null!)) - { - throw new ArgumentNullException(nameof(files)); - } - return this.Processing.QueueForExecutionAsync(() => + public Task AddOrUpdateSourceFilesAsync(ImmutableHashSet files, bool suppressVerification = false) => + this.Processing.QueueForExecutionAsync(() => { foreach (var file in files) { @@ -348,22 +304,14 @@ public Task AddOrUpdateSourceFilesAsync(ImmutableHashSet fil this.QueueGlobalTypeCheckingAsync(); } }); - } /// /// Modifies the compilation and all diagnostics to reflect the given change. - /// Throws an ArgumentNullException if any of the arguments is null. /// Throws a InvalidOperationException if file for which a change is given is not listed as source file. /// Throws an ArgumentException if the uri of the given text document identifier is null or not an absolute file uri. /// - public Task SourceFileDidChangeAsync(DidChangeTextDocumentParams param) - { - if (param?.ContentChanges == null) - { - throw new ArgumentNullException(nameof(param.ContentChanges)); - } - - return this.Processing.QueueForExecutionAsync(() => + public Task SourceFileDidChangeAsync(DidChangeTextDocumentParams param) => + this.Processing.QueueForExecutionAsync(() => { var docKey = GetFileId(param.TextDocument.Uri); var isSource = this.fileContentManagers.TryGetValue(docKey, out FileContentManager file); @@ -392,7 +340,6 @@ public Task SourceFileDidChangeAsync(DidChangeTextDocumentParams param) file.AddTimerTriggeredUpdateEvent(); } }); - } /// /// Called in order to process any queued changes in the file with the given URI and @@ -402,10 +349,7 @@ public Task SourceFileDidChangeAsync(DidChangeTextDocumentParams param) /// private Task TriggerFileUpdateAsync(Uri uri) { - if (!TryGetFileId(uri, out NonNullable docKey)) - { - throw new ArgumentException("invalid TextDocumentIdentifier"); - } + var docKey = GetFileId(uri); return this.Processing.QueueForExecutionAsync(() => { // Note that we cannot fail if the file is no longer part of the compilation, @@ -440,10 +384,7 @@ private Task TriggerFileUpdateAsync(Uri uri) /// public Task TryRemoveSourceFileAsync(Uri uri, bool publishEmptyDiagnostics = true) { - if (!TryGetFileId(uri, out NonNullable docKey)) - { - throw new ArgumentException("invalid TextDocumentIdentifier"); - } + var docKey = GetFileId(uri); return this.Processing.QueueForExecutionAsync(() => { if (!this.fileContentManagers.TryRemove(docKey, out FileContentManager file)) @@ -471,16 +412,11 @@ public Task TryRemoveSourceFileAsync(Uri uri, bool publishEmptyDiagnostics = tru /// and adapts all remaining diagnostics as needed. /// Does nothing if a file with the given Uri is not listed as source file. /// Spawns a compilation unit wide type checking unless suppressVerification is set to true, even if no files have been removed. - /// Throws an ArgumentNullException if the given sequence of files are null. - /// Throws an ArgumentException if the uri of the given text document identifier is null or not an absolute file uri. + /// Throws an ArgumentException if the uri of the given text document identifier is not an absolute file uri. /// public Task TryRemoveSourceFilesAsync(IEnumerable files, bool suppressVerification = false, bool publishEmptyDiagnostics = true) { - if (files == null) - { - throw new ArgumentNullException(nameof(files)); - } - if (files.Any(uri => !TryGetFileId(uri, out var _))) + if (files.Any(uri => !uri.IsAbsoluteUri || !uri.IsFile)) { throw new ArgumentException("invalid TextDocumentIdentifier"); } @@ -489,7 +425,7 @@ public Task TryRemoveSourceFilesAsync(IEnumerable files, bool suppressVerif { foreach (var uri in files) { - TryGetFileId(uri, out NonNullable docKey); + var docKey = GetFileId(uri); if (!this.fileContentManagers.TryRemove(docKey, out FileContentManager file)) { return; @@ -517,14 +453,9 @@ public Task TryRemoveSourceFilesAsync(IEnumerable files, bool suppressVerif /// /// Replaces the content from all referenced assemblies with the given references. /// Updates all diagnostics accordingly, unless suppressVerification has been set to true. - /// Throws an ArgumentNullException if the given references are null. /// internal Task UpdateReferencesAsync(References references, bool suppressVerification = false) { - if (references == null) - { - throw new ArgumentNullException(nameof(references)); - } return this.Processing.QueueForExecutionAsync(() => { this.compilationUnit.UpdateReferences(references); @@ -537,7 +468,6 @@ internal Task UpdateReferencesAsync(References references, bool suppressVerifica /// /// Replaces the content from all referenced assemblies with the given references, and updates all diagnostics accordingly. - /// Throws an ArgumentNullException if the given references are null. /// public Task UpdateReferencesAsync(References references) => this.UpdateReferencesAsync(references, false); @@ -640,23 +570,9 @@ private Task SpawnGlobalTypeCheckingAsync(bool runSynchronously = false) /// for all files that have not been modified while the type checking was running. Updates and publishes the semantic diagnostics for those files. /// For each file that has been modified while the type checking was running, /// queues a task calling TypeCheckFile on that file with the given cancellationToken. - /// Throws an ArgumentNullException if any of the given arguments is null. /// private void RunGlobalTypeChecking(CompilationUnit compilation, ImmutableDictionary content, CancellationToken cancellationToken) { - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - if (content == null) - { - throw new ArgumentNullException(nameof(content)); - } - if (cancellationToken == null) - { - throw new ArgumentNullException(nameof(cancellationToken)); - } - var diagnostics = QsCompilerError.RaiseOnFailure( () => TypeChecking.RunTypeChecking(compilation, content, cancellationToken), "error while running type checking in background"); @@ -719,14 +635,9 @@ private void RunGlobalTypeChecking(CompilationUnit compilation, ImmutableDiction /// If the given cancellation token is not cancellation requested, and the file with the document id is listed as source file, /// updates and resolves all global symbols for that file, and runs a type checking on the obtained content using the Compilation property. /// Replaces the header diagnostics and the semantic diagnostics in the file with the obtained diagnostics, and publishes them. - /// Throws an ArgumentNullException if the given cancellation token is null. /// private void TypeCheckFile(NonNullable fileId, CancellationToken cancellationToken) { - if (cancellationToken == null) - { - throw new ArgumentNullException(nameof(cancellationToken)); - } var isSource = this.fileContentManagers.TryGetValue(fileId, out FileContentManager file); if (!isSource || cancellationToken.IsCancellationRequested) { @@ -765,13 +676,17 @@ private void TypeCheckFile(NonNullable fileId, CancellationToken cancell /// or if some parameters are unspecified (null), /// or if the specified position is not a valid position within the file. /// - public WorkspaceEdit? Rename(RenameParams param) + public WorkspaceEdit? Rename(RenameParams? param) { - if (param is null || !TryGetFileId(param.TextDocument?.Uri, out NonNullable docKey)) + if (param?.TextDocument?.Uri is null + || !param.TextDocument.Uri.IsAbsoluteUri + || !param.TextDocument.Uri.IsFile) { return null; } + // FIXME: the correct thing to do here would be to call FlushAndExecute...! + var docKey = GetFileId(param.TextDocument.Uri); var success = this.Processing.QueueForExecution( () => this.fileContentManagers.TryGetValue(docKey, out FileContentManager file) ? file.Rename(this.compilationUnit, param.Position.ToQSharp(), param.NewName) @@ -811,10 +726,11 @@ private void TypeCheckFile(NonNullable fileId, CancellationToken cancell return null; } } - if (!TryGetFileId(textDocument?.Uri, out NonNullable docKey)) + if (textDocument?.Uri is null || !textDocument.Uri.IsAbsoluteUri || !textDocument.Uri.IsFile) { return null; } + var docKey = GetFileId(textDocument.Uri); var isSource = this.fileContentManagers.TryGetValue(docKey, out FileContentManager file); return isSource ? TryQueryFile(file) : null; } diff --git a/src/QsCompiler/CompilationManager/ContextBuilder.cs b/src/QsCompiler/CompilationManager/ContextBuilder.cs index 2a506abcc7..cb82645005 100644 --- a/src/QsCompiler/CompilationManager/ContextBuilder.cs +++ b/src/QsCompiler/CompilationManager/ContextBuilder.cs @@ -22,16 +22,10 @@ internal static class ContextBuilder /// /// Verifies that all tokens are ordered according to their range. - /// Throws an ArgumentNullException if the given tokens are null, or if any of the contained elements are. /// Throws an ArgumentException if this is not the case. /// internal static void VerifyTokenOrdering(IEnumerable tokens) { - if (tokens == null || tokens.Any(x => x == null)) - { - throw new ArgumentNullException(nameof(tokens)); - } - Position? previousEnding = null; foreach (var token in tokens) { @@ -46,14 +40,9 @@ internal static void VerifyTokenOrdering(IEnumerable tokens) /// /// Returns the TokenIndex for the first token in the given file, or null if no such token exists. - /// Throws an ArgumentNullException if file is null. /// internal static CodeFragment.TokenIndex? FirstToken(this FileContentManager file) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } var lineNr = 0; while (file.GetTokenizedLine(lineNr).Length == 0 && ++lineNr < file.NrLines()) { @@ -65,14 +54,9 @@ internal static void VerifyTokenOrdering(IEnumerable tokens) /// /// Returns the TokenIndex for the last token in the given file, or null if no such token exists. - /// Throws an ArgumentNullException if file is null. /// internal static CodeFragment.TokenIndex? LastToken(this FileContentManager file) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } var lastNonEmpty = file.NrLines(); while (lastNonEmpty-- > 0 && file.GetTokenizedLine(lastNonEmpty).Length == 0) { @@ -84,16 +68,9 @@ internal static void VerifyTokenOrdering(IEnumerable tokens) /// /// Returns true if the given token is fully included in the given range. - /// Throws an ArgumentNullException if the token is null. /// - internal static bool IsWithinRange(this CodeFragment token, Range range) - { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } - return range.Contains(token.Range.Start) && range.ContainsEnd(token.Range.End); - } + internal static bool IsWithinRange(this CodeFragment token, Range range) => + range.Contains(token.Range.Start) && range.ContainsEnd(token.Range.End); /// /// Returns a function that returns true if a given fragment ends at or before the given position. @@ -244,15 +221,10 @@ public static ((NonNullable, Position), (QsSpecializationKind?, Position /// Returns true if the given file contains any tokens overlapping with the given fragment. /// The range of the tokens in the file is assumed to be relative to their start line (the index at which they are listed), /// whereas the range of the given fragment is assumed to be the absolute range. - /// Throws an ArgumentNullException if the given file or range is null. /// Throws an ArgumentOutOfRangeException if the given range is not a valid range within file. /// internal static bool ContainsTokensOverlappingWith(this FileContentManager file, Range range) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } if (!file.ContainsRange(range)) { throw new ArgumentOutOfRangeException(nameof(range)); @@ -283,20 +255,10 @@ internal static bool ContainsTokensOverlappingWith(this FileContentManager file, /// /// Assuming both the current tokens and the tokens to update are sorted according to their range, /// merges the current and updated tokens such that the merged collection is sorted as well. - /// Throws an ArgumentNullException if either current or updated, or any of their elements are null. - /// Throws an ArgumentException if the token verification for the merged collection fails. + /// Throws a QsCompilerException if the token verification for the merged collection fails. /// internal static List MergeTokens(IEnumerable current, IEnumerable updated) { - if (current == null || current.Any(x => x == null)) - { - throw new ArgumentNullException(nameof(current)); - } - if (updated == null || updated.Any(x => x == null)) - { - throw new ArgumentNullException(nameof(updated)); - } - var merged = new List(0); void NextBatch(ref IEnumerable batch, IEnumerable next) { @@ -328,20 +290,9 @@ void NextBatch(ref IEnumerable batch, IEnumerable ne /// Comparing for equality by value, /// returns the index of the first element in the given list of CodeFragments that matches the given token, /// or -1 if no such element exists. - /// Throws an ArgumentNullException if the given list is null. /// internal static int FindByValue(this IReadOnlyList list, CodeFragment token) { - if (list == null) - { - throw new ArgumentNullException(nameof(list)); - } - if (token == null) - { - var nrNonNull = list.TakeWhile(x => x != null).Count(); - return nrNonNull == list.Count ? -1 : nrNonNull; - } - var index = -1; var tokenRange = token.Range; while (++index < list.Count && list[index].Range.Start < tokenRange.Start) @@ -353,15 +304,9 @@ internal static int FindByValue(this IReadOnlyList list, CodeFragm /// /// Returns the index of the closest preceding non-empty token with the next lower indentation level. /// Returns null if no such token exists. - /// Throws an ArgumentNullException if tIndex is null. /// internal static CodeFragment.TokenIndex? GetNonEmptyParent(this CodeFragment.TokenIndex tIndex) { - if (tIndex == null) - { - throw new ArgumentNullException(nameof(tIndex)); - } - var tokenIndex = new CodeFragment.TokenIndex(tIndex); var indentation = tokenIndex.GetFragment().Indentation; while ((tokenIndex = tokenIndex.Previous()) != null) @@ -377,14 +322,9 @@ internal static int FindByValue(this IReadOnlyList list, CodeFragm /// /// Returns an IEnumerable with the indices of the closest preceding non-empty tokens with increasingly lower indentation level. - /// Throws an ArgumentNullException if tIndex is null. /// internal static IEnumerable GetNonEmptyParents(this CodeFragment.TokenIndex tIndex) { - if (tIndex == null) - { - throw new ArgumentNullException(nameof(tIndex)); - } for (var current = tIndex.GetNonEmptyParent(); current != null; current = current.GetNonEmptyParent()) { yield return current; @@ -398,14 +338,9 @@ internal static int FindByValue(this IReadOnlyList list, CodeFragm /// up to the point where we are at the same indentation level again. /// If deep is set to false, then of those only the tokens with an indentation level that is precisely /// one larger than the one of the parent token are returned. - /// Throws an ArgumentNullException if tIndex is null. /// internal static IEnumerable GetChildren(this CodeFragment.TokenIndex tIndex, bool deep = true) { - if (tIndex == null) - { - throw new ArgumentNullException(nameof(tIndex)); - } var tokenIndex = new CodeFragment.TokenIndex(tIndex); var indentation = tokenIndex.GetFragment().Indentation; while ((tokenIndex = tokenIndex.Next()) != null && tokenIndex.GetFragment().Indentation > indentation) @@ -420,15 +355,9 @@ internal static int FindByValue(this IReadOnlyList list, CodeFragm /// /// Returns the index of the preceding non-empty token on the same indentation level, or null if no such token exists. /// Includes empty tokens if includeEmpty is set to true. - /// Throws an ArgumentNullException if tIndex is null. /// internal static CodeFragment.TokenIndex? PreviousOnScope(this CodeFragment.TokenIndex tIndex, bool includeEmpty = false) { - if (tIndex == null) - { - throw new ArgumentNullException(nameof(tIndex)); - } - var tokenIndex = new CodeFragment.TokenIndex(tIndex); var indentation = tokenIndex.GetFragment().Indentation; while ((tokenIndex = tokenIndex.Previous()) != null) @@ -445,15 +374,9 @@ internal static int FindByValue(this IReadOnlyList list, CodeFragm /// /// Returns the index of the next non-empty token on the same indenation level, or null if no such token exists. /// Includes empty tokens if includeEmpty is set to true. - /// Throws an ArgumentNullException if tIndex is null. /// internal static CodeFragment.TokenIndex? NextOnScope(this CodeFragment.TokenIndex tIndex, bool includeEmpty = false) { - if (tIndex == null) - { - throw new ArgumentNullException(nameof(tIndex)); - } - var tokenIndex = new CodeFragment.TokenIndex(tIndex); var indentation = tokenIndex.GetFragment().Indentation; while ((tokenIndex = tokenIndex.Next()) != null) @@ -471,14 +394,9 @@ internal static int FindByValue(this IReadOnlyList list, CodeFragm /// /// Returns the context object for the given token index, ignoring empty fragments. - /// Throws an ArgumentNullException if the given token index is null. /// private static Context.SyntaxTokenContext GetContext(this CodeFragment.TokenIndex tokenIndex) { - if (tokenIndex == null) - { - throw new ArgumentNullException(nameof(tokenIndex)); - } QsNullable Nullable(CodeFragment? token, bool precedesSelf) => token?.Kind == null ? QsNullable.Null @@ -501,19 +419,9 @@ QsNullable Nullable(CodeFragment? token, bool precedesSelf) => /// and adds the computed diagnostics to the ones returned as out parameter. /// Marks the token indices which are to be excluded from compilation due to context errors. /// Returns the line numbers for which the context diagnostics have been recomputed. - /// Throws an ArgumentNullException if any of the arguments is null. /// private static HashSet VerifyContext(this FileContentManager file, SortedSet changedLines, out List diagnostics) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (changedLines == null) - { - throw new ArgumentNullException(nameof(changedLines)); - } - IEnumerable TokenIndices(int lineNr) => Enumerable.Range(0, file.GetTokenizedLine(lineNr).Count()).Select(index => new CodeFragment.TokenIndex(file, lineNr, index)); @@ -567,19 +475,9 @@ List Verify(CodeFragment.TokenIndex tokenIndex) /// /// Given the line number of the lines that contain tokens that (possibly) have been modified, /// checks which callable declaration they can potentially belong to and returns the fully qualified name of those callables. - /// Throws an ArgumentNullException if the given file or the collection of changed lines is null. /// internal static IEnumerable<(Range, QsQualifiedName)> CallablesWithContentModifications(this FileContentManager file, IEnumerable changedLines) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (changedLines == null) - { - throw new ArgumentNullException(nameof(changedLines)); - } - var lastInFile = file.LastToken()?.GetFragment()?.Range?.End ?? file.End(); var callables = file.GetCallableDeclarations().Select(tuple => // these are sorted according to their line number { @@ -619,15 +517,9 @@ List Verify(CodeFragment.TokenIndex tokenIndex) /// Dequeues all lines whose tokens has changed and verifies the positions of these tokens. /// Does nothing if no lines have been modified. /// Recomputes and pushes the context diagnostics for the processed tokens otherwise. - /// Throws an ArgumentNullException if file is null. /// internal static void UpdateContext(this FileContentManager file) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - file.SyncRoot.EnterUpgradeableReadLock(); try { diff --git a/src/QsCompiler/CompilationManager/DataStructures.cs b/src/QsCompiler/CompilationManager/DataStructures.cs index e964387d10..b2f9bc98c1 100644 --- a/src/QsCompiler/CompilationManager/DataStructures.cs +++ b/src/QsCompiler/CompilationManager/DataStructures.cs @@ -147,7 +147,7 @@ private CodeFragment(int indent, Range range, string text, char next, QsComments throw new ArgumentException("a CodeFragment needs to be followed by a DelimitingChar"); } this.Indentation = indent < 0 ? throw new ArgumentException("indentation needs to be positive") : indent; - this.Text = text?.TrimEnd() ?? throw new ArgumentNullException(nameof(text)); + this.Text = text.TrimEnd(); this.FollowedBy = next; this.Comments = comments ?? QsComments.Empty; this.Kind = kind; // nothing here should be modifiable @@ -230,14 +230,12 @@ internal CodeFragment SetClosingComments(IEnumerable commentsAfter) /// /// Verifies the given line number and index *only* against the Tokens listed in file (and not against the content) /// and initializes an instance of TokenIndex. - /// Throws an ArgumentNullException if file is null. /// Throws an ArgumentOutOfRangeException if line or index are negative, /// or line is larger than or equal to the number of Tokens lists in file, /// or index is larger than or equal to the number of Tokens on the given line. /// internal TokenIndex(FileContentManager file, int line, int index) { - this.file = file ?? throw new ArgumentNullException(nameof(file)); if (line < 0 || line >= file.NrTokenizedLines()) { throw new ArgumentOutOfRangeException(nameof(line)); @@ -247,6 +245,7 @@ internal TokenIndex(FileContentManager file, int line, int index) throw new ArgumentOutOfRangeException(nameof(index)); } + this.file = file; this.Line = line; this.Index = index; } @@ -391,17 +390,15 @@ internal struct TreeNode /// Builds the TreeNode consisting of the given fragment and children. /// RelativeToRoot is set to the position of the fragment start relative to the given parent start position. /// Throws an ArgumentException if the given parent start position is larger than the fragment start position. - /// Throws an ArgumentNullException if any of the given arguments is null. /// public TreeNode(CodeFragment fragment, IReadOnlyList children, Position parentStart) { - this.Fragment = fragment ?? throw new ArgumentNullException(nameof(fragment)); - this.Children = children ?? throw new ArgumentNullException(nameof(children)); - if (fragment.Range.Start < parentStart) { throw new ArgumentException(nameof(parentStart), "parentStart needs to be smaller than or equal to the fragment start"); } + this.Fragment = fragment; + this.Children = children; this.RootPosition = parentStart; this.RelativePosition = fragment.Range.Start - parentStart; } @@ -445,11 +442,6 @@ private HeaderEntry( ImmutableArray doc, QsComments comments) { - if (tIndex == null) - { - throw new ArgumentNullException(nameof(tIndex)); - } - this.Position = offset; this.SymbolName = sym.Item1; this.PositionedSymbol = new Tuple, Range>(sym.Item1, sym.Item2); @@ -467,7 +459,6 @@ private HeaderEntry( /// If the keepInvalid parameter has been set to a (non-null) string, uses that string as the SymbolName for the returned HeaderEntry instance. /// Throws an ArgumentException if this verification fails as well. /// Throws an ArgumentException if the extracted declaration is Null. - /// Throws an ArgumentNullException if the given token index is null. /// internal static HeaderEntry? From( Func>> getDeclaration, @@ -476,15 +467,6 @@ private HeaderEntry( ImmutableArray doc, string? keepInvalid = null) { - if (getDeclaration == null) - { - throw new ArgumentNullException(nameof(getDeclaration)); - } - if (tIndex == null) - { - throw new ArgumentNullException(nameof(tIndex)); - } - var fragment = tIndex.GetFragmentWithClosingComments(); var extractedDecl = getDeclaration(fragment); var (sym, decl) = @@ -520,7 +502,7 @@ internal class FileHeader // *don't* dispose of the sync root! public FileHeader(ReaderWriterLockSlim syncRoot) { - this.SyncRoot = syncRoot ?? throw new ArgumentNullException(nameof(syncRoot)); + this.SyncRoot = syncRoot; this.namespaceDeclarations = new ManagedSortedSet(syncRoot); this.openDirectives = new ManagedSortedSet(syncRoot); this.typeDeclarations = new ManagedSortedSet(syncRoot); @@ -935,10 +917,6 @@ public void SetItem(int index, T newItem) public void Replace(int start, int count, IReadOnlyList replacements) { - if (replacements == null) - { - throw new ArgumentNullException(nameof(replacements)); - } this.SyncRoot.EnterWriteLock(); try { @@ -963,10 +941,6 @@ public void Replace(int start, int count, IReadOnlyList replacements) public void ReplaceAll(IEnumerable replacement) { - if (replacement == null) - { - throw new ArgumentNullException(nameof(replacement)); - } this.SyncRoot.EnterWriteLock(); try { @@ -980,10 +954,6 @@ public void ReplaceAll(IEnumerable replacement) public void ReplaceAll(ManagedList replacement) { - if (replacement == null) - { - throw new ArgumentNullException(nameof(replacement)); - } this.SyncRoot.EnterWriteLock(); try { @@ -997,10 +967,6 @@ public void ReplaceAll(ManagedList replacement) public void Transform(int index, Func transformation) { - if (transformation == null) - { - throw new ArgumentNullException(nameof(transformation)); - } this.SyncRoot.EnterWriteLock(); try { @@ -1014,10 +980,6 @@ public void Transform(int index, Func transformation) public void Transform(Func transformation) { - if (transformation == null) - { - throw new ArgumentNullException(nameof(transformation)); - } this.SyncRoot.EnterWriteLock(); try { diff --git a/src/QsCompiler/CompilationManager/DiagnosticTools.cs b/src/QsCompiler/CompilationManager/DiagnosticTools.cs index 9ffb43ce01..f17496a92b 100644 --- a/src/QsCompiler/CompilationManager/DiagnosticTools.cs +++ b/src/QsCompiler/CompilationManager/DiagnosticTools.cs @@ -64,16 +64,11 @@ range is null /// /// Returns a copy of this diagnostic with the given offset added to the line numbers. /// - /// Thrown if is null. /// /// Thrown if the new diagnostic has negative line numbers. /// public static Diagnostic WithLineNumOffset(this Diagnostic diagnostic, int offset) { - if (diagnostic is null) - { - throw new ArgumentNullException(nameof(diagnostic)); - } var copy = diagnostic.Copy(); copy.Range.Start.Line += offset; copy.Range.End.Line += offset; @@ -124,31 +119,17 @@ public static bool IsInformation(this Diagnostic m) => /// /// Extracts all elements satisfying the given condition and which start at a line that is larger or equal to lowerBound. /// Diagnostics without any range information are only extracted if no lower bound is specified or the specified lower bound is smaller than zero. - /// Throws an ArgumentNullException if the given condition is null. /// [return: NotNullIfNotNull("orig")] - public static IEnumerable? Filter(this IEnumerable orig, Func condition, int lowerBound = -1) - { - if (condition == null) - { - throw new ArgumentNullException(nameof(condition)); - } - return orig?.Where(m => condition(m) && lowerBound <= (m.Range?.Start?.Line ?? -1)); - } + public static IEnumerable? Filter(this IEnumerable? orig, Func condition, int lowerBound = -1) => + orig?.Where(m => condition(m) && lowerBound <= (m.Range?.Start?.Line ?? -1)); /// /// Extracts all elements satisfying the given condition and which start at a line that is larger or equal to lowerBound and smaller than upperBound. - /// Throws an ArgumentNullException if the given condition is null. /// [return: NotNullIfNotNull("orig")] - public static IEnumerable? Filter(this IEnumerable orig, Func condition, int lowerBound, int upperBound) - { - if (condition == null) - { - throw new ArgumentNullException(nameof(condition)); - } - return orig?.Where(m => condition(m) && lowerBound <= m.Range.Start.Line && m.Range.End.Line < upperBound); - } + public static IEnumerable? Filter(this IEnumerable? orig, Func condition, int lowerBound, int upperBound) => + orig?.Where(m => condition(m) && lowerBound <= m.Range.Start.Line && m.Range.End.Line < upperBound); /// /// Extracts all elements which start at a line that is larger or equal to lowerBound. diff --git a/src/QsCompiler/CompilationManager/Diagnostics.cs b/src/QsCompiler/CompilationManager/Diagnostics.cs index f512056eb7..10824ac563 100644 --- a/src/QsCompiler/CompilationManager/Diagnostics.cs +++ b/src/QsCompiler/CompilationManager/Diagnostics.cs @@ -79,16 +79,10 @@ private static string Code(QsCompilerDiagnostic msg) /// Generates a suitable Diagnostic from the given CompilerDiagnostic returned by the Q# compiler. /// The message range contained in the given CompilerDiagnostic is first converted to a Position object, /// and then added to the given positionOffset if the latter is not null. - /// Throws an ArgumentNullException if the Range of the given CompilerDiagnostic is null. /// Throws an ArgumentOutOfRangeException if the contained range contains zero or negative entries, or if its Start is bigger than its End. /// - internal static Diagnostic Generate(string filename, QsCompilerDiagnostic msg, Position? positionOffset = null) - { - if (msg.Range == null) - { - throw new ArgumentNullException(nameof(msg.Range)); - } - return new Diagnostic + internal static Diagnostic Generate(string filename, QsCompilerDiagnostic msg, Position? positionOffset = null) => + new Diagnostic { Severity = Severity(msg), Code = Code(msg), @@ -96,7 +90,6 @@ internal static Diagnostic Generate(string filename, QsCompilerDiagnostic msg, P Message = msg.Message, Range = ((positionOffset ?? Position.Zero) + msg.Range).ToLsp() }; - } internal const string QsCodePrefix = "QS"; diff --git a/src/QsCompiler/CompilationManager/EditorSupport/CodeActions.cs b/src/QsCompiler/CompilationManager/EditorSupport/CodeActions.cs index 618ce7e93a..e447dc137a 100644 --- a/src/QsCompiler/CompilationManager/EditorSupport/CodeActions.cs +++ b/src/QsCompiler/CompilationManager/EditorSupport/CodeActions.cs @@ -25,19 +25,9 @@ internal static class SuggestedEdits { /// /// Returns the given edit for the specified file as WorkspaceEdit. - /// Throws an ArgumentNullException if the given file or any of the given edits is null. /// private static WorkspaceEdit GetWorkspaceEdit(this FileContentManager file, params TextEdit[] edits) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (edits == null || edits.Any(edit => edit == null)) - { - throw new ArgumentNullException(nameof(edits)); - } - var versionedFileId = new VersionedTextDocumentIdentifier { Uri = file.Uri, Version = 1 }; // setting version to null here won't work in VS Code ... return new WorkspaceEdit { diff --git a/src/QsCompiler/CompilationManager/EditorSupport/CodeCompletion.cs b/src/QsCompiler/CompilationManager/EditorSupport/CodeCompletion.cs index b56b2ea5be..c05e12edad 100644 --- a/src/QsCompiler/CompilationManager/EditorSupport/CodeCompletion.cs +++ b/src/QsCompiler/CompilationManager/EditorSupport/CodeCompletion.cs @@ -135,14 +135,9 @@ internal static class CodeCompletion /// Returns the completion environment at the given position in the file or null if the environment cannot be /// determined. Stores the code fragment found at or before the given position into an out parameter. /// - /// Thrown when any argument is null. private static (CompletionScope?, QsFragmentKind?) GetCompletionEnvironment( FileContentManager file, Position position, out CodeFragment? fragment) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } if (!file.ContainsPosition(position)) { // FileContentManager.IndentationAt will fail if the position is not within the file. @@ -207,7 +202,6 @@ private static (CompletionScope?, QsFragmentKind?) GetCompletionEnvironment( /// /// Returns completion items that match the given kind. /// - /// Thrown when any argument is null. private static IEnumerable GetCompletionsForKind( FileContentManager file, CompilationUnit compilation, @@ -215,23 +209,6 @@ private static IEnumerable GetCompletionsForKind( CompletionKind kind, string namespacePrefix = "") { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - if (kind == null) - { - throw new ArgumentNullException(nameof(kind)); - } - if (namespacePrefix == null) - { - throw new ArgumentNullException(nameof(namespacePrefix)); - } - switch (kind) { case CompletionKind.Member member: @@ -279,23 +256,9 @@ private static IEnumerable GetCompletionsForKind( /// part of a qualified symbol, in which case only completions for symbols matching the namespace prefix will be /// included. /// - /// Thrown when any argument is null. private static IEnumerable GetFallbackCompletions( FileContentManager file, CompilationUnit compilation, Position position) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - if (position == null) - { - throw new ArgumentNullException(nameof(position)); - } - // If the character at the position is a dot but no valid namespace path precedes it (for example, in a // decimal number), then no completions are valid here. var nsPath = GetSymbolNamespacePath(file, position); @@ -332,20 +295,9 @@ private static IEnumerable GetFallbackCompletions( /// Returns completions for local variables at the given position. If is true, /// shows only completions for mutable local variables. Returns an empty enumerator if the position is invalid. /// - /// Thrown when any argument is null. private static IEnumerable GetLocalCompletions( - FileContentManager file, CompilationUnit compilation, Position position, bool mutableOnly = false) - { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - return - compilation + FileContentManager file, CompilationUnit compilation, Position position, bool mutableOnly = false) => + compilation .TryGetLocalDeclarations(file, position, out _, includeDeclaredAtPosition: false) .Variables .Where(variable => !mutableOnly || variable.InferredInformation.IsMutable) @@ -354,34 +306,17 @@ private static IEnumerable GetLocalCompletions( Label = variable.VariableName.Value, Kind = CompletionItemKind.Variable }); - } /// /// Returns completions for all accessible callables given the current namespace and the list of open /// namespaces, or an empty enumerable if symbols haven't been resolved yet. /// - /// - /// Thrown when any argument except is null. - /// private static IEnumerable GetCallableCompletions( FileContentManager file, CompilationUnit compilation, string? currentNamespace, IEnumerable openNamespaces) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - if (openNamespaces == null) - { - throw new ArgumentNullException(nameof(openNamespaces)); - } - if (!compilation.GlobalSymbols.ContainsResolutions) { return Array.Empty(); @@ -407,28 +342,12 @@ private static IEnumerable GetCallableCompletions( /// Returns completions for all accessible types given the current namespace and the list of open namespaces, or /// an empty enumerable if symbols haven't been resolved yet. /// - /// - /// Thrown when any argument except is null. - /// private static IEnumerable GetTypeCompletions( FileContentManager file, CompilationUnit compilation, string? currentNamespace, IEnumerable openNamespaces) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - if (openNamespaces == null) - { - throw new ArgumentNullException(nameof(openNamespaces)); - } - if (!compilation.GlobalSymbols.ContainsResolutions) { return Array.Empty(); @@ -452,14 +371,8 @@ private static IEnumerable GetTypeCompletions( /// Returns completions for all named items in any accessible type, or an empty enumerable if symbols haven't /// been resolved yet. /// - /// Thrown when the argument is null. private static IEnumerable GetNamedItemCompletions(CompilationUnit compilation) { - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - if (!compilation.GlobalSymbols.ContainsResolutions) { return Array.Empty(); @@ -481,19 +394,9 @@ private static IEnumerable GetNamedItemCompletions(CompilationUn /// Note: a dot will be added after the given prefix if it is not the empty string, and doesn't already end with /// a dot. /// - /// Thrown when any argument is null. private static IEnumerable GetGlobalNamespaceCompletions( CompilationUnit compilation, string prefix = "") { - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - if (prefix == null) - { - throw new ArgumentNullException(nameof(prefix)); - } - if (prefix.Length != 0 && !prefix.EndsWith(".")) { prefix += "."; @@ -518,23 +421,9 @@ private static IEnumerable GetGlobalNamespaceCompletions( /// Note: a dot will be added after the given prefix if it is not the empty string, and doesn't already end with /// a dot. /// - /// Thrown when any argument is null. private static IEnumerable GetNamespaceAliasCompletions( FileContentManager file, CompilationUnit compilation, Position position, string prefix = "") { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - if (prefix == null) - { - throw new ArgumentNullException(nameof(prefix)); - } - if (prefix.Length != 0 && !prefix.EndsWith(".")) { prefix += "."; @@ -564,21 +453,12 @@ private static IEnumerable GetNamespaceAliasCompletions( /// the compilation unit with the given qualified name. Returns null if no documentation is available or the /// completion item data is missing properties. /// - /// Thrown when any argument is null. private static string? TryGetDocumentation( CompilationUnit compilation, CompletionItemData data, CompletionItemKind kind, bool useMarkdown) { - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - if (data == null) - { - throw new ArgumentNullException(nameof(data)); - } if (data.QualifiedName == null - || data.SourceFile == null - || !compilation.GlobalSymbols.NamespaceExists(data.QualifiedName.Namespace)) + || data.SourceFile == null + || !compilation.GlobalSymbols.NamespaceExists(data.QualifiedName.Namespace)) { return null; } @@ -611,19 +491,9 @@ private static IEnumerable GetNamespaceAliasCompletions( /// Returns the names of all namespaces that have been opened without an alias and are accessible from the given /// position in the file. Returns an empty enumerator if the position is invalid. /// - /// Thrown when any argument is null. private static IEnumerable GetOpenNamespaces( FileContentManager file, CompilationUnit compilation, Position position) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - var @namespace = file.TryGetNamespaceAt(position); if (@namespace == null || !compilation.GlobalSymbols.NamespaceExists(NonNullable.New(@namespace))) { @@ -640,14 +510,8 @@ private static IEnumerable GetOpenNamespaces( /// Returns the namespace path for the qualified symbol at the given position, or null if there is no qualified /// symbol. /// - /// Thrown when any argument is null. private static string? GetSymbolNamespacePath(FileContentManager file, Position position) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - var fragment = file.TryGetFragmentAt(position, out _, includeEnd: true); if (fragment == null) { @@ -669,18 +533,8 @@ private static IEnumerable GetOpenNamespaces( /// Returns the index in the fragment text corresponding to the given absolute position. /// /// Thrown when the position is outside the fragment range. - /// Thrown when any argument is null. private static int GetTextIndexFromPosition(CodeFragment fragment, Position position) { - if (fragment == null) - { - throw new ArgumentNullException(nameof(fragment)); - } - if (position == null) - { - throw new ArgumentNullException(nameof(position)); - } - var relativeLine = position.Line - fragment.Range.Start.Line; var lines = Utils.SplitLines(fragment.Text).DefaultIfEmpty(""); var relativeCharacter = @@ -699,23 +553,9 @@ private static int GetTextIndexFromPosition(CodeFragment fragment, Position posi /// Resolves the namespace alias and returns its full namespace name. If the alias couldn't be resolved, returns /// the alias unchanged. /// - /// Thrown when any argument is null. private static string ResolveNamespaceAlias( FileContentManager file, CompilationUnit compilation, Position position, string alias) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - if (alias == null) - { - throw new ArgumentNullException(nameof(alias)); - } - var nsName = file.TryGetNamespaceAt(position); if (nsName == null || !compilation.GlobalSymbols.NamespaceExists(NonNullable.New(nsName))) { @@ -729,14 +569,8 @@ private static string ResolveNamespaceAlias( /// Returns the token index at, or the closest token index before, the given position. Returns null if there is /// no token at or before the given position. /// - /// Thrown when any argument is null. private static CodeFragment.TokenIndex? GetTokenAtOrBefore(FileContentManager file, Position position) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - var line = position.Line; var tokens = file.GetTokenizedLine(line); @@ -758,22 +592,12 @@ private static string ResolveNamespaceAlias( /// Returns the position of the delimiting character that follows the given code fragment. /// /// Thrown when the code fragment has a missing delimiter. - /// Thrown when any argument is null. private static Position GetDelimiterPosition(FileContentManager file, CodeFragment fragment) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (fragment == null) - { - throw new ArgumentNullException(nameof(fragment)); - } if (fragment.FollowedBy == CodeFragment.MissingDelimiter) { throw new ArgumentException("Code fragment has a missing delimiter", nameof(fragment)); } - var end = fragment.Range.End; var position = file.FragmentEnd(ref end); return Position.Create(position.Line, position.Column - 1); @@ -794,14 +618,9 @@ private static bool IsPositionAfterDelimiter( /// position is after the end of the fragment text but before the delimiter, the entire text is returned with a /// space character appended to it. /// - /// Thrown when file or position is null. private static string GetFragmentTextBeforePosition( FileContentManager file, CodeFragment? fragment, Position position) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } if (fragment == null || IsPositionAfterDelimiter(file, fragment, position)) { return ""; diff --git a/src/QsCompiler/CompilationManager/EditorSupport/SymbolInformation.cs b/src/QsCompiler/CompilationManager/EditorSupport/SymbolInformation.cs index b0ddfb765d..6bd7b7d4e5 100644 --- a/src/QsCompiler/CompilationManager/EditorSupport/SymbolInformation.cs +++ b/src/QsCompiler/CompilationManager/EditorSupport/SymbolInformation.cs @@ -26,9 +26,6 @@ internal static class SymbolInfo { // utils for getting the necessary information for editor commands - /// - /// Throws an ArgumentNullException if the given offset or relative range is null. - /// internal static Location AsLocation(NonNullable source, Position offset, Range relRange) => new Location { @@ -36,9 +33,6 @@ internal static Location AsLocation(NonNullable source, Position offset, Range = (offset + relRange).ToLsp() }; - /// - /// Throws an ArgumentNullException if the given reference location is null. - /// internal static Location AsLocation(IdentifierReferences.Location loc) => AsLocation(loc.SourceFile, loc.DeclarationOffset + loc.RelativeStatementLocation.Offset, loc.SymbolRange); @@ -258,7 +252,7 @@ spec.Implementation is SpecializationImplementation.Provided impl && spec.Locati : ImmutableHashSet.Empty) .Select(AsLocation); } - else if (implementation is null) + else if (implementation is null || specPos is null) { return false; } diff --git a/src/QsCompiler/CompilationManager/FileContentManager.cs b/src/QsCompiler/CompilationManager/FileContentManager.cs index 92fbcfd4d9..6eb4c3e07a 100644 --- a/src/QsCompiler/CompilationManager/FileContentManager.cs +++ b/src/QsCompiler/CompilationManager/FileContentManager.cs @@ -111,7 +111,7 @@ internal void TriggerGlobalTypeChecking() => internal FileContentManager(Uri uri, NonNullable fileName) { this.SyncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); - this.Uri = uri ?? throw new ArgumentNullException(nameof(uri)); + this.Uri = uri; this.FileName = fileName; this.content = new ManagedList(this.SyncRoot); @@ -189,14 +189,9 @@ internal ImmutableArray CurrentSemanticDiagnostics() => /// Given the position where the syntax check starts and ends relative to the original file content before the update, and the lineNrChange, /// removes all diagnostics that are no longer valid due to that change, and /// updates the line numbers of the remaining diagnostics if needed. - /// Throws an ArgumentNullException if the given diagnostics to update or if the syntax check delimiters are null. /// private static void InvalidateOrUpdateBySyntaxCheckDelimeters(ManagedList diagnostics, Range syntaxCheckDelimiters, int lineNrChange) { - if (diagnostics == null) - { - throw new ArgumentNullException(nameof(diagnostics)); - } Diagnostic UpdateLineNrs(Diagnostic m) => m.SelectByStart(syntaxCheckDelimiters.End) ? m.WithLineNumOffset(lineNrChange) : m; diagnostics.SyncRoot.EnterWriteLock(); try @@ -219,7 +214,6 @@ private static void InvalidateOrUpdateBySyntaxCheckDelimeters(ManagedList /// Updates the line numbers of diagnostics that start after the syntax check end delimiter in both lists of diagnostics, /// and removes all diagnostics that overlap with the given range for the syntax check update in the updated diagnostics only. - /// Throws an ArgumentNullException if the given current and/or latest diagnostics are null, or if the syntax check delimiters are null. /// Throws an ArgumentException if the given start and end position do not denote a valid range. /// private static void DelayInvalidateOrUpdate( @@ -228,15 +222,6 @@ private static void DelayInvalidateOrUpdate( Range syntaxCheckDelimiters, int lineNrChange) { - if (diagnostics == null) - { - throw new ArgumentNullException(nameof(diagnostics)); - } - if (updated == null) - { - throw new ArgumentNullException(nameof(updated)); - } - InvalidateOrUpdateBySyntaxCheckDelimeters(updated, syntaxCheckDelimiters, lineNrChange); Diagnostic UpdateLineNrs(Diagnostic m) => m.SelectByStart(syntaxCheckDelimiters.End) ? m.WithLineNumOffset(lineNrChange) : m; if (lineNrChange != 0) @@ -304,7 +289,6 @@ internal void AddSyntaxDiagnostics(IEnumerable updates) => /// Given the position where the syntax check starts and ends relative to the original file content before the update, and the lineNrChange, /// removes all diagnostics that are no longer valid due to that change, and /// updates the line numbers of the remaining diagnostics if needed. - /// Throws an ArgumentNullException if the given diagnostics to update or the syntax check delimiters are null. /// Throws an ArgumentException if the given start and end position do not denote a valid range. /// private void InvalidateOrUpdateSyntaxDiagnostics(Range syntaxCheckDelimiters, int lineNrChange) => @@ -314,15 +298,10 @@ private void InvalidateOrUpdateSyntaxDiagnostics(Range syntaxCheckDelimiters, in /// Given the line numbers for which the context diagnostics are now obsolete, /// removes all context diagnostics that start on a line marked as obsolete, /// and replaces them with the given sequence of context diagnostics. - /// Throws an ArgumentNullException if the if the given sequence of line numbers for which the context diagnostics are obsolete is null. /// Throws an ArgumentOutOfRangeException if that sequence contains a value that is negative. /// internal void UpdateContextDiagnostics(HashSet obsolete, IEnumerable updates) { - if (obsolete == null) - { - throw new ArgumentNullException(nameof(obsolete)); - } if (obsolete.Any() && obsolete.Min() < 0) { throw new ArgumentOutOfRangeException(nameof(obsolete)); @@ -394,7 +373,6 @@ internal void ReplaceHeaderDiagnostics(IEnumerable updates) /// Given the position where the syntax check starts and ends relative to the original file content before the update, and the lineNrChange, /// removes all diagnostics that are no longer valid due to that change, and /// updates the line numbers of the remaining diagnostics if needed. - /// Throws an ArgumentNullException if the given diagnostics to update or the syntax check delimiters are null. /// Throws an ArgumentException if the given start and end position do not denote a valid range. /// private void InvalidateOrUpdateHeaderDiagnostics(Range syntaxCheckDelimiters, int lineNrChange) => @@ -422,7 +400,6 @@ internal void AddAndFinalizeSemanticDiagnostics(IEnumerable updates) /// Given the position where the syntax check starts and ends relative to the original file content before the update, and the lineNrChange, /// removes all diagnostics that are no longer valid due to that change, and /// updates the line numbers of the remaining diagnostics if needed. - /// Throws an ArgumentNullException if the given diagnostics to update or the syntax check delimiters are null. /// Throws an ArgumentException if the given start and end position do not denote a valid range. /// private void InvalidateOrUpdateSemanticDiagnostics(Range syntaxCheckDelimiters, int lineNrChange) => @@ -469,7 +446,6 @@ public PublishDiagnosticParams Diagnostics() internal int NrLines() => this.content.Count(); /// - /// Throws an ArgumentNullException if any of the given arguments is null. /// Throws an ArgumentOutOfRangeException if start and count are not valid for the current file content, where count needs to be at least one. /// Throws an ArgumentException if the replacements do not at least contain one element, or the indentation change is non-zero, /// or if a replacement does not have a suitable line ending. @@ -484,11 +460,6 @@ private void VerifyContentUpdate(int start, int count, IReadOnlyList r { throw new ArgumentOutOfRangeException(nameof(count)); } - // make sure properties are never set to null! - if (replacements == null) - { - throw new ArgumentNullException(nameof(replacements)); - } if (replacements.Count == 0) { throw new ArgumentException("expecting at least on replacement"); @@ -634,7 +605,6 @@ private void VerifyTokenUpdate(IReadOnlyList fragments) /// Applies ModifiedTokens to the tokens at the given lineNr to obtain the list of tokens for which to mark all connections as edited. /// Then constructs and returns an Action as out parameter /// that adds lineNr as well as all lines containing connections to mark to EditedTokens. - /// Throws an ArgumentNullException if UpdatedTokens or ModifiedTokens is null. /// Throws an ArgumentException if any of the values returned by UpdatedTokens or ModifiedTokens is null. /// Throws an ArgumentOutOfRangeException if linrNr is not a valid index for the current Tokens. /// @@ -648,14 +618,6 @@ private void TransformAndMarkEdited( this.tokens.SyncRoot.EnterWriteLock(); try { - if (updatedTokens == null) - { - throw new ArgumentNullException(nameof(updatedTokens)); - } - if (modifiedTokens == null) - { - throw new ArgumentNullException(nameof(modifiedTokens)); - } if (lineNr < 0 || lineNr >= this.tokens.Count()) { throw new ArgumentOutOfRangeException(nameof(lineNr)); @@ -708,7 +670,6 @@ private void TransformAndMarkEdited( /// marks the lines with the removed tokens as well as any lines that contain connected tokens as edited. /// Tokens starting at range.End or ending at range.Start are *not* considered to be overlapping. /// Futs a write-lock on the Tokens during the entire routine. - /// Throws an ArgumentNullException if the given range or it start or end position is null. /// Throws an ArgumentOutOfRangeException if the line number of the range end is larger than the number of currently saved tokens. /// private void RemoveTokensInRange(Range range) @@ -784,14 +745,9 @@ void FilterAndMarkEdited(int index, Func predicate) /// Attaches end of line comments for the lines on which fragments have been modified to suitable tokens. /// Verifies the given fragments and /// throws the corresponding exception if the verification fails. - /// Throws an ArgumentNullException if any of the given fragments are null. /// internal void TokensUpdate(IReadOnlyList fragments) { - if (fragments == null || fragments.Any(x => x == null)) - { - throw new ArgumentNullException(nameof(fragments)); - } if (!fragments.Any()) { return; @@ -1031,17 +987,12 @@ internal void ClearVerification() /// An update is considered necessary if the given change replaces more than one line of the current content, /// or if the inserted text cannot be a symbol or keyword (i.e. includes any whitespace, numbers and/or special characters). /// Sets the out parameter to true if diagnostics are to be published. - /// Throws an ArgumentNullException if the change or any of its fields are null. /// Throws an ArgumentException if the range of the change is invalid. /// internal void PushChange(TextDocumentContentChangeEvent change, out bool publishDiagnostics) { // NOTE: since there may be still unprocessed changes aggregated in UnprocessedChanges we cannot verify the range of the change against the current file content, - // however, let's at least check that nothing is null, all entries are positive, and the range start is smaller than or equal to the range end - if (change == null) - { - throw new ArgumentNullException(nameof(change)); - } + // however, let's at least check that all entries are positive, and the range start is smaller than or equal to the range end this.timer.Stop(); // will be restarted if needed var range = change.Range.ToQSharp(); @@ -1084,17 +1035,12 @@ internal void PushChange(TextDocumentContentChangeEvent change, out bool publish /// /// Replaces the entire file content with the given text. /// Forces the update to be processed rather than queued. - /// Throws an ArgumentNullException if the given text is null. /// internal void ReplaceFileContent(string text) { this.SyncRoot.EnterUpgradeableReadLock(); try { - if (text == null) - { - throw new ArgumentNullException(nameof(text)); - } var change = new TextDocumentContentChangeEvent { Range = new Lsp.Range { Start = new Lsp.Position(), End = this.End().ToLsp() }, diff --git a/src/QsCompiler/CompilationManager/ProcessingQueue.cs b/src/QsCompiler/CompilationManager/ProcessingQueue.cs index 563c9d919c..0f438a71c3 100644 --- a/src/QsCompiler/CompilationManager/ProcessingQueue.cs +++ b/src/QsCompiler/CompilationManager/ProcessingQueue.cs @@ -58,14 +58,9 @@ public void Complete() => /// /// Enqueues the given Action for exclusive (serialized) execution. /// Uses the set exception logger to log any exception that occurs during execution. - /// Throws an ArgumentNullException if the given Action is null. /// public Task QueueForExecutionAsync(Action processing) { - if (processing == null) - { - throw new ArgumentNullException(nameof(processing)); - } var processingTask = this.ProcessingTaskAsync(processing); processingTask.Start(this.scheduler.ExclusiveScheduler); return processingTask; @@ -74,37 +69,26 @@ public Task QueueForExecutionAsync(Action processing) /// /// Executes the given Action synchronously, with no exclusive actions running. /// Uses the set exception logger to log any exception that occurs during execution. - /// Throws an ArgumentNullException if the given Action is null. /// NOTE: may deadlock if the given function to execute calls this processing queue. /// - public void QueueForExecution(Action processing) - { - if (processing == null) - { - throw new ArgumentNullException(nameof(processing)); - } + public void QueueForExecution(Action processing) => this.QueueForExecution( () => { processing(); return new object(); - }, out _); - } + }, + out _); /// /// Executes the given function synchronously without any exclusive tasks running, /// returning its result as out parameter. /// Uses the set exception logger to log any exception that occurs during execution. /// Returns true if the execution succeeded without throwing an exception, and false otherwise. - /// Throws an ArgumentNullException if the given function to execute is null. /// NOTE: may deadlock if the given function to execute calls this processing queue. /// public bool QueueForExecution(Func execute, [MaybeNull] out T result) { - if (execute == null) - { - throw new ArgumentNullException(nameof(execute)); - } T res = default(T); var succeeded = true; this.QueueForExecutionAsync(() => @@ -130,14 +114,9 @@ public bool QueueForExecution(Func execute, [MaybeNull] out T result) /// /// Enqueues the given Action for concurrent (background) execution. /// Uses the set exception logger to log any exception that occurs during execution. - /// Throws an ArgumentNullException if the given Action is null. /// public Task ConcurrentExecutionAsync(Action processing) { - if (processing == null) - { - throw new ArgumentNullException(nameof(processing)); - } var processingTask = this.ProcessingTaskAsync(processing); processingTask.Start(this.scheduler.ConcurrentScheduler); return processingTask; @@ -146,36 +125,25 @@ public Task ConcurrentExecutionAsync(Action processing) /// /// Executes the given Action synchronously and concurrently (background). /// Uses the set exception logger to log any exception that occurs during execution. - /// Throws an ArgumentNullException if the given Action is null. /// NOTE: may deadlock if the given function to execute calls this processing queue. /// - public void ConcurrentExecution(Action processing) - { - if (processing == null) - { - throw new ArgumentNullException(nameof(processing)); - } + public void ConcurrentExecution(Action processing) => this.ConcurrentExecution( () => { processing(); return new object(); - }, out _); - } + }, + out _); /// /// Executes the given function synchronously and concurrently, returning its result as out parameter. /// Returns true if the execution succeeded without throwing an exception, and false otherwise. /// Uses the set exception logger to log any exception that occurs during execution. - /// Throws an ArgumentNullException if the given Action is null. /// NOTE: may deadlock if the given function to execute calls this processing queue. /// public bool ConcurrentExecution(Func execute, [MaybeNull] out T result) { - if (execute == null) - { - throw new ArgumentNullException(nameof(execute)); - } T res = default(T); var succeeded = true; this.ConcurrentExecutionAsync(() => diff --git a/src/QsCompiler/CompilationManager/ProjectManager.cs b/src/QsCompiler/CompilationManager/ProjectManager.cs index 0ad42a3005..24defec15f 100644 --- a/src/QsCompiler/CompilationManager/ProjectManager.cs +++ b/src/QsCompiler/CompilationManager/ProjectManager.cs @@ -36,7 +36,7 @@ public ProjectProperties( bool loadTestNames) { this.Version = version ?? ""; - this.OutputPath = outputPath ?? throw new ArgumentNullException(nameof(outputPath)); + this.OutputPath = outputPath; this.RuntimeCapabilities = runtimeCapabilities; this.IsExecutable = isExecutable; this.ProcessorArchitecture = processorArchitecture; @@ -81,9 +81,9 @@ public ProjectInformation( { this.Properties = new ProjectProperties( version, outputPath, runtimeCapabilities, isExecutable, processorArchitecture, loadTestNames); - this.SourceFiles = sourceFiles?.ToImmutableArray() ?? throw new ArgumentNullException(nameof(sourceFiles)); - this.ProjectReferences = projectReferences?.ToImmutableArray() ?? throw new ArgumentNullException(nameof(projectReferences)); - this.References = references?.ToImmutableArray() ?? throw new ArgumentNullException(nameof(references)); + this.SourceFiles = sourceFiles.ToImmutableArray(); + this.ProjectReferences = projectReferences.ToImmutableArray(); + this.References = references.ToImmutableArray(); } } @@ -163,7 +163,6 @@ public void Dispose() => /// Initializes the project for the given project file with the given project information. /// If an Action for publishing diagnostics is given and not null, /// that action is called whenever diagnostics for the project have changed and are ready for publishing. - /// Throws an ArgumentNullException if the given project file or project information is null. /// internal Project( Uri projectFile, @@ -172,8 +171,8 @@ internal Project( Action? publishDiagnostics, Action? log) { - this.ProjectFile = projectFile ?? throw new ArgumentNullException(nameof(projectFile)); - this.Properties = projectInfo?.Properties ?? throw new ArgumentNullException(nameof(projectInfo)); + this.ProjectFile = projectFile; + this.Properties = projectInfo.Properties; this.SetProjectInformation(projectInfo); var version = Version.TryParse(projectInfo.Properties.Version, out Version v) ? v : null; @@ -204,14 +203,9 @@ internal Project( /// Sets the output path and all specified source files, references and project references /// to those specified by the given project information. /// Generates a suitable diagnostics if the output uri cannot be determined. - /// Throws an ArgumentNullException if the given project information is null. /// private void SetProjectInformation(ProjectInformation projectInfo) { - if (projectInfo == null) - { - throw new ArgumentNullException(nameof(projectInfo)); - } this.Properties = projectInfo.Properties; this.isLoaded = false; @@ -249,17 +243,12 @@ private void SetProjectInformation(ProjectInformation projectInfo) /// Calls the given action RemoveFiles with the uris of all files that are no longer part of this project. /// Calls the given function GetExistingFileManagers to get all existing managers for the files that are newly part of this project. /// Does *not* update the content of already existing file managers. - /// Throws an ArgumentNullException if the given dictionary to determine the output path for project references is null. /// private void LoadProject( IDictionary projectOutputPaths, Func, Uri, IEnumerable>? getExistingFileManagers, Action, Task>? removeFiles) { - if (projectOutputPaths == null) - { - throw new ArgumentNullException(nameof(projectOutputPaths)); - } if (this.isLoaded) { return; @@ -288,19 +277,13 @@ private void LoadProject( /// Calls the given action RemoveFiles with the uris of all files that are no longer part of this project. /// Calls the given function GetExistingFileManagers to get all existing managers for the files that are newly part of this project. /// Does *not* update the content of already existing file managers. - /// Throws an ArgumentNullException if the given dictionary to determine the output path for project references is. /// internal Task LoadProjectAsync( IDictionary projectOutputPaths, Func, Uri, IEnumerable>? getExistingFileManagers, Action, Task>? removeFiles, - ProjectInformation? projectInfo = null) - { - if (projectOutputPaths == null) - { - throw new ArgumentNullException(nameof(projectOutputPaths)); - } - return this.processing.QueueForExecutionAsync(() => + ProjectInformation? projectInfo = null) => + this.processing.QueueForExecutionAsync(() => { if (projectInfo != null) { @@ -308,7 +291,6 @@ internal Task LoadProjectAsync( } this.LoadProject(projectOutputPaths, getExistingFileManagers, removeFiles); }); - } // private routines used whenever the project itself is updated // -> need to be called from within appropriately queued routines only! @@ -318,20 +300,9 @@ internal Task LoadProjectAsync( /// Returns a function that given the uri to a project files, returns the corresponding output path, /// if the corrsponding entry in the given dictionary indeed exist. /// If no such entry exists, generates a suitable error messages and adds it to the given list of diagnostics. - /// Throws an ArgumentNullException if the given diagnostics are null, or - /// if the given dictionary mapping each project files to the corresponding output path of the built project dll is. /// private static Func GetProjectOutputPath(IDictionary projectOutputPaths, List diagnostics) => (projFile) => { - if (projectOutputPaths == null) - { - throw new ArgumentNullException(nameof(projectOutputPaths)); - } - if (diagnostics == null) - { - throw new ArgumentNullException(nameof(diagnostics)); - } - if (projectOutputPaths.TryGetValue(projFile, out var referencedProj)) { return referencedProj; @@ -347,20 +318,10 @@ internal Task LoadProjectAsync( /// If skipVerification is set to true, does push the updated project references to the CompilationUnitManager, /// but suppresses the compilation unit wide type checking that would usually ensue. /// Otherwise replaces *all* project references in the CompilationUnitManager with the newly loaded ones. - /// Throws an ArgumentNullException if the given sequence of project references is null. /// private Task LoadProjectReferencesAsync( IDictionary projectOutputPaths, IEnumerable projectReferences, bool skipVerification = false) { - if (projectOutputPaths == null) - { - throw new ArgumentNullException(nameof(projectOutputPaths)); - } - if (projectReferences == null) - { - throw new ArgumentNullException(nameof(projectReferences)); - } - var diagnostics = new List(); var loadedHeaders = LoadProjectReferences( projectReferences, @@ -383,24 +344,16 @@ private Task LoadProjectReferencesAsync( /// Updates the reloaded reference in the CompilationUnitManager. /// Publishes the updated load diagnostics using the publisher of the CompilationUnitManager. /// Does nothing if the given project reference is not referenced by this project. - /// Throws an ArgumentNullException if the given dictionary is null. /// Throws an ArgumentException if the given Uri is not an absolute uri to a file. /// private void ReloadProjectReference(IDictionary projectOutputPaths, Uri projectReference) { - if (projectOutputPaths == null) - { - throw new ArgumentNullException(nameof(projectOutputPaths)); - } - if (!CompilationUnitManager.TryGetFileId(projectReference, out var projRefId)) - { - throw new ArgumentException("expecting an absolute file uri"); - } if (!this.specifiedProjectReferences.Contains(projectReference) || !this.isLoaded) { return; } + var projRefId = CompilationUnitManager.GetFileId(projectReference); var diagnostics = new List(); var loadedHeaders = LoadProjectReferences( new string[] { projectReference.LocalPath }, @@ -431,15 +384,9 @@ private void ReloadProjectReference(IDictionary projectOutputPaths, U /// If skipVerification is set to true, does push the updated references to the CompilationUnitManager, /// but suppresses the compilation unit wide type checking that would usually ensue. /// Otherwise replaces *all* references in the CompilationUnitManager with the newly loaded ones. - /// Throws an ArgumentNullException if the given sequence of referenced dlls is null. /// private Task LoadReferencedAssembliesAsync(IEnumerable references, bool skipVerification = false) { - if (references == null) - { - throw new ArgumentNullException(nameof(references)); - } - var diagnostics = new List(); var loadedHeaders = LoadReferencedAssemblies( references, @@ -463,15 +410,12 @@ private Task LoadReferencedAssembliesAsync(IEnumerable references, bool /// private void ReloadReferencedAssembly(Uri reference) { - if (!CompilationUnitManager.TryGetFileId(reference, out var refId)) - { - throw new ArgumentException("expecting an absolute file uri"); - } if (!this.specifiedReferences.Contains(reference) || !this.isLoaded) { return; } + var refId = CompilationUnitManager.GetFileId(reference); var diagnostics = new List(); var loadedHeaders = LoadReferencedAssemblies( new string[] { reference.LocalPath }, @@ -509,7 +453,6 @@ private void ReloadReferencedAssembly(Uri reference) /// is *not* updated in the CompilationUnitManager. /// Otherwise the FileContentManager of all files is replaced by a new one initialized with the content from disk. /// *Always* spawns a compilation unit wide type checking! - /// Throws an ArgumentNullException if the given sequence of source files is null. /// private Task LoadSourceFilesAsync( IEnumerable sourceFiles, @@ -517,10 +460,6 @@ private Task LoadSourceFilesAsync( Action, Task>? removeFiles, bool skipIfAlreadyLoaded = false) { - if (sourceFiles == null) - { - throw new ArgumentNullException(nameof(sourceFiles)); - } var diagnostics = new List(); var loaded = LoadSourceFiles(sourceFiles, diagnostics.Add, this.Manager.LogException); this.sourceFileDiagnostics = diagnostics.ToImmutableArray(); @@ -568,19 +507,9 @@ private PublishDiagnosticParams CurrentLoadDiagnostics() /// Given a dictionary mapping each project files to the corresponding output path of the built project dll, /// as well as a uri to the assembly to reload, reloads all project references with that output path, and/or any reference to that dll. /// Updates the load diagnostics accordingly, and publishes them using the publisher of the CompilationUnitManager. - /// Throws an ArgumentNullException if any of the given arguments is null. /// public Task ReloadAssemblyAsync(IDictionary projectOutputPaths, Uri dllPath) { - if (projectOutputPaths == null) - { - throw new ArgumentNullException(nameof(projectOutputPaths)); - } - if (dllPath == null) - { - throw new ArgumentNullException(nameof(dllPath)); - } - var projectsWithThatOutputDll = projectOutputPaths.Where(pair => pair.Value == dllPath).Select(pair => pair.Key); return this.processing.QueueForExecutionAsync(() => { @@ -600,22 +529,10 @@ public Task ReloadAssemblyAsync(IDictionary projectOutputPaths, Uri d /// Updates the reloaded reference in the CompilationUnitManager. /// Publishes the updated load diagnostics using the publisher of the CompilationUnitManager. /// Does nothing if the given project reference is not referenced by this project. - /// Throws an ArgumentNullException if any of the given arguments is null. /// - public Task ReloadProjectReferenceAsync(IDictionary projectOutputPaths, Uri projectReference) - { - if (projectOutputPaths == null) - { - throw new ArgumentNullException(nameof(projectOutputPaths)); - } - if (projectReference == null) - { - throw new ArgumentNullException(nameof(projectReference)); - } - - return this.processing.QueueForExecutionAsync(() => + public Task ReloadProjectReferenceAsync(IDictionary projectOutputPaths, Uri projectReference) => + this.processing.QueueForExecutionAsync(() => this.ReloadProjectReference(projectOutputPaths, projectReference)); - } /// /// Given a uri to source file to reload, reloads that source file, and updates all load diagnostics accordingly, @@ -624,14 +541,9 @@ public Task ReloadProjectReferenceAsync(IDictionary projectOutputPath /// updates the content of the source file in the CompilationUnitManager. /// Publishes the updated load diagnostics using the publisher of the CompilationUnitManager. /// Does nothing if the given source file is open in the editor or not listed as a source file of this project. - /// Throws an ArgumentNullException if the given uri is null. /// public Task ReloadSourceFileAsync(Uri sourceFile, Func? openInEditor = null) { - if (sourceFile == null) - { - throw new ArgumentNullException(nameof(sourceFile)); - } openInEditor ??= _ => null; return this.processing.QueueForExecutionAsync(() => @@ -667,24 +579,9 @@ public Task ReloadSourceFileAsync(Uri sourceFile, Func /// /// If the given file is a loaded source file of this project, /// executes the given task for that file on the CompilationUnitManager. - /// Throws an ArgumentNullException if the given uri, the task to execute, - /// or the dictionary to determine the output path for project references is null. /// public bool ManagerTask(Uri file, Action executeTask, IDictionary projectOutputPaths) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (executeTask == null) - { - throw new ArgumentNullException(nameof(executeTask)); - } - if (projectOutputPaths == null) - { - throw new ArgumentNullException(nameof(projectOutputPaths)); - } - this.processing.QueueForExecution( () => { @@ -774,15 +671,9 @@ public void Dispose() => /// Returns a function that given the uris of all files that have been added to a project, /// queries openInEditor to determine which of those files are currently open in the editor. /// Removes all such files from the default manager and returns their FileContentManagers. - /// Throws an ArgumentNullException if the given function openInEditor is null. /// - private Func, Uri, IEnumerable> MigrateToProject(Func openInEditor) - { - if (openInEditor == null) - { - throw new ArgumentNullException(nameof(openInEditor)); - } - return (filesAddedToProject, projFile) => + private Func, Uri, IEnumerable> MigrateToProject(Func openInEditor) => + (filesAddedToProject, projFile) => { filesAddedToProject ??= ImmutableHashSet.Empty; var openFiles = filesAddedToProject.SelectNotNull(openInEditor).ToImmutableArray(); @@ -798,7 +689,6 @@ private Func, Uri, IEnumerable> Migrat } return openFiles; }; - } /// /// Returns a function that given the uris of all files that have been removed from a project, @@ -807,16 +697,9 @@ private Func, Uri, IEnumerable> Migrat /// Clears all verifications for those files and adds them to the default manager. /// The returned Action does nothing if the task passed as argument has been cancelled. /// The returned Action throws an ObjectDisposedException if the task passed as argument has been disposed. - /// The returned Action throws an ArgumentNullException if the task passed as argument is null. - /// Throws an ArgumentNullException if the given function openInEditor is null. /// - private Action, Task> MigrateToDefaultManager(Func openInEditor) - { - if (openInEditor == null) - { - throw new ArgumentNullException(nameof(openInEditor)); - } - return (filesRemovedFromProject, removal) => + private Action, Task> MigrateToDefaultManager(Func openInEditor) => + (filesRemovedFromProject, removal) => { if (removal.IsCanceled) { @@ -832,7 +715,6 @@ private Action, Task> MigrateToDefaultManager(Func? openInEditor = null) { - if (projectFiles == null || projectFiles.Contains(null!)) - { - throw new ArgumentNullException(nameof(projectFiles)); - } - if (projectLoader == null) - { - throw new ArgumentNullException(nameof(projectLoader)); - } openInEditor ??= _ => null; return this.load.QueueForExecutionAsync(() => @@ -892,14 +766,6 @@ public Task ProjectChangedOnDiskAsync( ProjectInformation.Loader projectLoader, Func? openInEditor = null) { - if (projectFile == null) - { - throw new ArgumentNullException(nameof(projectFile)); - } - if (projectLoader == null) - { - throw new ArgumentNullException(nameof(projectLoader)); - } openInEditor ??= _ => null; // TODO: allow to cancel this task via cancellation token? @@ -944,13 +810,8 @@ public Task ProjectChangedOnDiskAsync( /// To be called whenever one of the tracked projects has been added, removed or updated /// in order to update all other projects referencing the modified one. /// - private Task ProjectReferenceChangedOnDiskChangeAsync(Uri projFile) - { - if (projFile == null) - { - throw new ArgumentNullException(nameof(projFile)); - } - return this.load.QueueForExecutionAsync(() => + private Task ProjectReferenceChangedOnDiskChangeAsync(Uri projFile) => + this.load.QueueForExecutionAsync(() => { var projectOutputPaths = this.projects.ToImmutableDictionary(p => p.Key, p => p.Value.OutputPath); foreach (var project in this.projects.Values) @@ -958,19 +819,13 @@ private Task ProjectReferenceChangedOnDiskChangeAsync(Uri projFile) project.ReloadProjectReferenceAsync(projectOutputPaths, projFile); } }); - } /// /// To be called whenever a dll that may be referenced by one of the tracked projects is added, removed or changed on disk /// in order to update all projects referencing it accordingly. /// - public Task AssemblyChangedOnDiskAsync(Uri dllPath) - { - if (dllPath == null) - { - throw new ArgumentNullException(nameof(dllPath)); - } - return this.load.QueueForExecutionAsync(() => + public Task AssemblyChangedOnDiskAsync(Uri dllPath) => + this.load.QueueForExecutionAsync(() => { var projectOutputPaths = this.projects.ToImmutableDictionary(p => p.Key, p => p.Value.OutputPath); foreach (var project in this.projects.Values) @@ -978,7 +833,6 @@ public Task AssemblyChangedOnDiskAsync(Uri dllPath) project.ReloadAssemblyAsync(projectOutputPaths, dllPath); } }); - } /// /// To be called whenever a source file that may belong to one of the tracked projects has changed on disk. @@ -986,20 +840,14 @@ public Task AssemblyChangedOnDiskAsync(Uri dllPath) /// if the modified file is a source file of that project and not open in the editor /// (i.e. openInEditor is null or returns null for that file) at the time of execution. /// - public Task SourceFileChangedOnDiskAsync(Uri sourceFile, Func? openInEditor = null) - { - if (sourceFile == null) - { - throw new ArgumentNullException(nameof(sourceFile)); - } - return this.load.QueueForExecutionAsync(() => + public Task SourceFileChangedOnDiskAsync(Uri sourceFile, Func? openInEditor = null) => + this.load.QueueForExecutionAsync(() => { foreach (var project in this.projects.Values) { project.ReloadSourceFileAsync(sourceFile, openInEditor); } }); - } // routines related to querying individual compilation managers (internally and externally) @@ -1025,15 +873,9 @@ public Task SourceFileChangedOnDiskAsync(Uri sourceFile, Func - public Task ManagerTaskAsync(Uri file, Action executeTask) - { - if (executeTask == null) - { - throw new ArgumentNullException(nameof(executeTask)); - } - return this.load.QueueForExecutionAsync(() => + public Task ManagerTaskAsync(Uri file, Action executeTask) => + this.load.QueueForExecutionAsync(() => { var didExecute = false; var options = new ParallelOptions { TaskScheduler = TaskScheduler.Default }; @@ -1050,7 +892,6 @@ public Task ManagerTaskAsync(Uri file, Action exec executeTask(this.defaultManager, false); } }); - } // editor commands that require blocking @@ -1307,8 +1148,9 @@ public Task ManagerTaskAsync(Uri file, Action exec // static routines related to loading the content needed for compilation public static string MessageSource(Uri uri) => - CompilationUnitManager.TryGetFileId(uri, out NonNullable source) ? source.Value - : uri != null ? uri.AbsolutePath : throw new ArgumentNullException(nameof(uri)); + uri.IsAbsoluteUri && uri.IsFile + ? CompilationUnitManager.GetFileId(uri).Value + : uri.AbsolutePath; /// /// For the given sequence of file names verifies that a file with the corresponding full path exists, @@ -1319,7 +1161,6 @@ public static string MessageSource(Uri uri) => /// Generates suitable diagnostics for duplicate and not found files, and for invalid paths. /// Logs the generated diagnostics using onDiagnostics if the action has been specified and is not null. /// Catches exceptions related to path errors and logs them using onException if the action has been specified and is not null. - /// Throws an ArgumentNullException if the given sequence of files is null. /// public static IEnumerable FilterFiles( IEnumerable files, @@ -1331,10 +1172,6 @@ public static IEnumerable FilterFiles( Action? onDiagnostic = null, Action? onException = null) { - if (files == null) - { - throw new ArgumentNullException(nameof(files)); - } var exceptions = new List<(string, Exception)>(); Uri? WithFullPath(string file) { @@ -1380,17 +1217,12 @@ public static IEnumerable FilterFiles( /// Generates a suitable error whenever the file content could not be loaded. /// Calls the given onDiagnostic action on all generated diagnostics. /// Returns the uri and file content for each file that could be loaded. - /// Throws an ArgumentNullException if the given sequence of source files is null. /// public static ImmutableDictionary LoadSourceFiles( IEnumerable sourceFiles, Action? onDiagnostic = null, Action? onException = null) { - if (sourceFiles == null) - { - throw new ArgumentNullException(nameof(sourceFiles)); - } string? GetFileContent(Uri file) { try @@ -1425,7 +1257,6 @@ public static ImmutableDictionary LoadSourceFiles( /// Generates suitable diagostics if the specified assembly could not be found or its content could not be loaded, /// and calls the given onDiagnostic action on all generated diagnostics. /// Catches any thrown exception and calls onException on it if it is specified and not null. - /// Throws an ArgumentNullException if the given uri is null. /// private static References.Headers? LoadReferencedDll( Uri asm, @@ -1433,10 +1264,6 @@ public static ImmutableDictionary LoadSourceFiles( Action? onDiagnostic = null, Action? onException = null) { - if (asm == null) - { - throw new ArgumentNullException(nameof(asm)); - } try { try @@ -1485,7 +1312,6 @@ private static NonNullable GetFileId(Uri uri) => /// If no file exists at the returned path, generates a suitable error message. /// Calls the given onDiagnostic action on all generated diagnostics. /// Returns a dictionary that maps each project file for which the corresponding dll content could be loaded to the Q# attributes it contains. - /// Throws an ArgumentNullException if the given sequence of project references or the given GetOutputPath function is null. /// public static ImmutableDictionary, References.Headers> LoadProjectReferences( IEnumerable refProjectFiles, @@ -1493,14 +1319,6 @@ private static NonNullable GetFileId(Uri uri) => Action? onDiagnostic = null, Action? onException = null) { - if (refProjectFiles == null) - { - throw new ArgumentNullException(nameof(refProjectFiles)); - } - if (getOutputPath == null) - { - throw new ArgumentNullException(nameof(getOutputPath)); - } References.Headers? LoadReferencedDll(Uri asm) => ProjectManager.LoadReferencedDll(asm, false, onException: onException); // any exception here is really a failure of GetOutputPath and will be treated as an unexpected exception @@ -1548,7 +1366,6 @@ private static NonNullable GetFileId(Uri uri) => /// Generates a suitable error message for each binary file that could not be loaded. /// Calls the given onDiagnostic action on all generated diagnostics. /// Returns a dictionary that maps each existing dll to the Q# attributes it contains. - /// Throws an ArgumentNullException if the given sequence of referenced binaries is null. /// public static ImmutableDictionary, References.Headers> LoadReferencedAssemblies( IEnumerable references, @@ -1556,10 +1373,6 @@ private static NonNullable GetFileId(Uri uri) => Action? onException = null, bool ignoreDllResources = false) { - if (references == null) - { - throw new ArgumentNullException(nameof(references)); - } References.Headers? LoadReferencedDll(Uri asm) => ProjectManager.LoadReferencedDll(asm, ignoreDllResources, onDiagnostic, onException); diff --git a/src/QsCompiler/CompilationManager/ScopeTracking.cs b/src/QsCompiler/CompilationManager/ScopeTracking.cs index 8b9ac936dd..baf560171b 100644 --- a/src/QsCompiler/CompilationManager/ScopeTracking.cs +++ b/src/QsCompiler/CompilationManager/ScopeTracking.cs @@ -18,18 +18,9 @@ public static class ScopeTracking /// /// Checks that all delimiters are within -1 and the string length, and that they are sorted in ascending order. /// Throws an ArgumentException if the checks fail. - /// Throws an ArgumentNullException if any of the given arguments is null. /// internal static void VerifyStringDelimiters(string text, IEnumerable delimiters) { - if (text == null) - { - throw new ArgumentNullException(nameof(text)); - } - if (delimiters == null) - { - throw new ArgumentNullException(nameof(delimiters)); - } var last = -2; foreach (int delim in delimiters) { @@ -53,19 +44,9 @@ internal static void VerifyStringDelimiters(string text, IEnumerable delimi /// Checks that all positions are a valid index in the line text, and that they are sorted in ascending order. /// Checks that none of the positions lays within a string. /// Throws an ArgumentException if the checks fail. - /// Throws an ArgumentNullException if any of the given arguments is null. /// internal static void VerifyExcessBracketPositions(CodeLine line, IEnumerable positions) { - if (line == null) - { - throw new ArgumentNullException(nameof(line)); - } - if (positions == null) - { - throw new ArgumentNullException(nameof(positions)); - } - var last = -1; foreach (var pos in positions) { @@ -89,15 +70,10 @@ internal static void VerifyExcessBracketPositions(CodeLine line, IEnumerable internal static int GetIndentationChange(FileContentManager file, int continueAt, CodeLine previous) // previous: last element before the one at continueAt { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } if (continueAt < 0 || continueAt > file.NrLines()) { throw new ArgumentOutOfRangeException(nameof(continueAt)); @@ -130,15 +106,9 @@ private static bool ContinueString(CodeLine? line) /// /// Computes the location of the string delimiters within a given text. - /// Throws an ArgumentNullException if the given text is null. /// private static IEnumerable ComputeStringDelimiters(string text, bool isContinuation) { - if (text == null) - { - throw new ArgumentNullException(nameof(text)); - } - var nrDelimiters = 0; if (isContinuation) { @@ -195,14 +165,9 @@ private static IEnumerable ComputeStringDelimiters(string text, bool isCont /// /// Given an index computed before applying RemoveStrings, computes the index after applying RemoveStrings. /// Returns -1 if the given index is within a string. - /// Throws an ArgumentNullException if delimiters is null. /// private static int IndexExcludingStrings(int indexInFullText, IEnumerable delimiters) { - if (delimiters == null) - { - throw new ArgumentNullException(nameof(delimiters)); - } var iter = delimiters.GetEnumerator(); var index = indexInFullText; int GetStart(int pos) => pos < 0 ? 0 : StartDelimiter(pos); @@ -225,14 +190,9 @@ private static int IndexExcludingStrings(int indexInFullText, IEnumerable d /// /// Given and index computed before applying RelevantCode, computes the index after applying RelevantCode. /// Returns -1 if the given index is negative, or is within a string or a comment, or denotes an excess bracket. - /// Throws an ArgumentNullException if line is null. /// private static int IndexInRelevantCode(int indexInFullText, CodeLine line) { - if (line == null) - { - throw new ArgumentNullException(nameof(line)); - } if (indexInFullText < 0 || line.WithoutEnding.Length <= indexInFullText) { return -1; @@ -260,14 +220,9 @@ private static int IndexInRelevantCode(int indexInFullText, CodeLine line) /// /// Given an index computed after applying RemoveStrings, computes the index in the original text. - /// Throws an ArgumentNullException if delimiters is null. /// private static int IndexIncludingStrings(int indexInTrimmed, IEnumerable delimiters) { - if (delimiters == null) - { - throw new ArgumentNullException(nameof(delimiters)); - } var iter = delimiters.GetEnumerator(); var index = indexInTrimmed; int GetStart(int pos) => pos < 0 ? 0 : StartDelimiter(pos); @@ -284,7 +239,6 @@ private static int IndexIncludingStrings(int indexInTrimmed, IEnumerable de /// /// Given an index computed after applying RelevantCode, computes the index in the original text. - /// Throws an ArgumentNullException if line is null. /// private static int IndexInFullString(int indexInTrimmed, CodeLine line) { @@ -352,7 +306,6 @@ private static string RelevantCode(CodeLine line) /// /// Computes the string delimiters for a truncated substring of length count starting at start based on the delimiters of the original string. - /// Throws an ArgumentNullException if the given delimiters are null. /// Throws an ArgumentException if start or count is smaller than zero. /// private static IEnumerable TruncateStringDelimiters(IEnumerable delimiters, int start, int count) @@ -365,10 +318,6 @@ private static IEnumerable TruncateStringDelimiters(IEnumerable delimi { throw new ArgumentOutOfRangeException(nameof(count)); } - if (delimiters == null) - { - throw new ArgumentNullException(nameof(delimiters)); - } var nrDelim = 0; delimiters = delimiters.SkipWhile(delim => delim < start && ++nrDelim > 0); @@ -395,14 +344,9 @@ private static IEnumerable TruncateStringDelimiters(IEnumerable delimi /// The returned index is relative to the original text. /// If the value returned by FindIndex is smaller than zero it is returned unchanged. /// Throws an ArgumentOutOfRangeException if start and count do not define a valid range in the text of the given line. - /// Throws an ArgumentNullException if any of the given arguments is null. /// internal static int FindInCode(this CodeLine line, Func findIndex, bool ignoreExcessBrackets = true) { - if (findIndex == null) - { - throw new ArgumentNullException(nameof(findIndex)); - } if (ignoreExcessBrackets) { return IndexInFullString(findIndex(RelevantCode(line)), line); // fine also for index = -1 @@ -419,11 +363,10 @@ internal static int FindInCode(this CodeLine line, Func findIndex, /// Important: This function returns the index relative to the original text, not the substring. /// If the value returned by FindIndex is smaller than zero it is returned unchanged. /// Throws an ArgumentOutOfRangeException if start and count do not define a valid range in the text of the given line. - /// Throws an ArgumentNullException if any of the given arguments is null. /// internal static int FindInCode(this CodeLine line, Func findIndex, int start, int count, bool ignoreExcessBrackets = true) { - var truncatedDelims = TruncateStringDelimiters(line.StringDelimiters, start, count); // TruncateStringDelimiters will throw if line is null + var truncatedDelims = TruncateStringDelimiters(line.StringDelimiters, start, count); var truncatedText = line.Text.Substring(start, count); // will throw if start and count are out of range var truncatedExcessClosings = line.ExcessBracketPositions @@ -475,23 +418,9 @@ internal static int IndentationAt(this FileContentManager file, Position pos) // utils for computing indentations and excess closings - private static int NrIndents(string text) - { - if (text == null) - { - throw new ArgumentNullException(nameof(text)); - } - return text.Length - text.Replace("{", "").Length; - } + private static int NrIndents(string text) => text.Length - text.Replace("{", "").Length; - private static int NrUnindents(string text) - { - if (text == null) - { - throw new ArgumentNullException(nameof(text)); - } - return text.Length - text.Replace("}", "").Length; - } + private static int NrUnindents(string text) => text.Length - text.Replace("}", "").Length; /// /// Returns the indentation at the end of the line. @@ -506,7 +435,6 @@ private static int FinalIndentation(this CodeLine line) /// /// Computes the number of excess brackets on the given line based in the given line number /// and the list of lines containing the excess closings before that line. - /// Throws an ArgumentNullException if any of the arguments is null. /// private static int[] ComputeExcessClosings(CodeLine line, int effectiveIndent) { @@ -553,14 +481,9 @@ private static int[] ComputeExcessClosings(CodeLine line, int effectiveIndent) /// with suitable string delimiters and the correct end of line comment position, /// leaving the indentation at its default value and the excess brackets uncomputed. /// The previous line being null or not provided indicates that there is no previous line. - /// Throws an ArgumentNullExceptions if the given texts are null. /// private static IEnumerable InitializeCodeLines(IEnumerable texts, CodeLine? previousLine = null) { - if (texts == null) - { - throw new ArgumentNullException(nameof(texts)); - } var continueString = ContinueString(previousLine); foreach (string text in texts) { @@ -579,14 +502,9 @@ private static IEnumerable InitializeCodeLines(IEnumerable tex /// Given the initial indentation of a sequence of CodeLines, and a sequence of code lines with the correct string delimiters set, /// computes and sets the correct indentation level and excess bracket positions for each line. /// The previous line being null or not provided indicates that there is no previous line. - /// Throws an ArgumentNullExceptions if the given texts are null. /// private static IEnumerable SetIndentations(IEnumerable lines, int currentIndentation) { - if (lines == null) - { - throw new ArgumentNullException(nameof(lines)); - } foreach (var line in lines) { var updated = line.SetIndentation(currentIndentation); @@ -616,40 +534,25 @@ private static IEnumerable SetIndentations(IEnumerable lines /// /// Based on the previous line, computes the new CodeLines for the given texts. /// The previous line being null or not provided indicates that there is no previous line. - /// Throws an ArgumentNullExceptions if the given texts are null. /// - private static IEnumerable ComputeCodeLines(IEnumerable texts, CodeLine? previousLine = null) - { - return SetIndentations(InitializeCodeLines(texts, previousLine), previousLine == null ? 0 : previousLine.FinalIndentation()); - } + private static IEnumerable ComputeCodeLines(IEnumerable texts, CodeLine? previousLine = null) => + SetIndentations(InitializeCodeLines(texts, previousLine), previousLine == null ? 0 : previousLine.FinalIndentation()); /// /// Returns an enumerable sequence of new CodeLines when the initial indentation of the sequence is initialIndentation, /// (re-)computing the positions of excess brackets if needed. - /// Throws an ArgumentNullException if the given sequence of code lines is null. /// - private static List GetUpdatedLines(this IEnumerable lines, int initialIndentation) - { - return SetIndentations(lines, initialIndentation).ToList(); - } + private static List GetUpdatedLines(this IEnumerable lines, int initialIndentation) => + SetIndentations(lines, initialIndentation).ToList(); /// /// Computes the excess closing and scope error updates for the given replacements at the position specified by start and count in the given file. /// Returns a sequence of CodeLines for the remaining file, if the made replacements require updating the remaining file as well, and null otherwise. - /// Throws an ArgumentNullException if file or replacements is null. /// Throws an ArgumentException if replacements does not at least contain one CodeLine. /// Throws an ArgumentOutOfRangeException if the range defined by start and count is not within the given file, where count needs to be at least one. /// private static IEnumerable? ComputeUpdates(FileContentManager file, int start, int count, CodeLine[] replacements) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (replacements == null) - { - throw new ArgumentNullException(nameof(replacements)); - } if (start < 0 || start >= file.NrLines()) { throw new ArgumentOutOfRangeException(nameof(start)); @@ -692,15 +595,10 @@ private static List GetUpdatedLines(this IEnumerable lines, /// /// Given the total number of excess closings in the file /// checks for both an unclosed scope and a missing string ending on lastLine, and adds the corresponding error(s) to updatedScopeErrors. - /// Throws an ArgumentNullException if file is null. /// Throws an ArgumentException if the number of lines in the file is zero. /// private static IEnumerable CheckForMissingClosings(this FileContentManager file) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } if (file.NrLines() == 0) { throw new ArgumentException("the number of lines in a file can never be zero"); @@ -718,15 +616,10 @@ private static IEnumerable CheckForMissingClosings(this FileContentM /// /// Computes excess bracket errors for the given range of lines in file based on the corresponding CodeLine. - /// Throws an ArgumentNullException if file is null. /// Throws an ArgumentOutOfRangeException if the range [start, start + count) is not within file. /// private static IEnumerable ComputeScopeDiagnostics(this FileContentManager file, int start, int count) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } foreach (var line in file.GetLines(start, count)) { foreach (var pos in line.ExcessBracketPositions) @@ -739,14 +632,10 @@ private static IEnumerable ComputeScopeDiagnostics(this FileContentM /// /// Computes excess bracket errors for the given range of lines in file based on the corresponding CodeLine. - /// Throws an ArgumentNullException if file is null. /// Throws an ArgumentOutOfRangeException if start is not within file. /// - private static IEnumerable ComputeScopeDiagnostics(this FileContentManager file, int start) - { - // will raise an exception if file is null - return ComputeScopeDiagnostics(file, start, file == null ? 0 : file.NrLines() - start); - } + private static IEnumerable ComputeScopeDiagnostics(this FileContentManager file, int start) => + ComputeScopeDiagnostics(file, start, file == null ? 0 : file.NrLines() - start); // the actual update routine @@ -798,16 +687,9 @@ private static void Update(this FileContentManager file, int start, int count, I /// Attempts to compute an incremental update for the change specified by start, count and newText, and updates file accordingly. /// The given argument newText replaces the entire lines from start to (but not including) start + count. /// If the given change is null, then (only) the currently queued unprocessed changes are processed. - /// Throws an ArgumentNullException if file is null. - /// Any other exceptions should be throws (and caught, and possibly re-thrown) during the updating. /// internal static void UpdateScopeTacking(this FileContentManager file, TextDocumentContentChangeEvent? change) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - /// /// Replaces the lines in the range [start, end] with those for the given text. /// diff --git a/src/QsCompiler/CompilationManager/TextProcessor.cs b/src/QsCompiler/CompilationManager/TextProcessor.cs index f078fec173..a0b635ef24 100644 --- a/src/QsCompiler/CompilationManager/TextProcessor.cs +++ b/src/QsCompiler/CompilationManager/TextProcessor.cs @@ -7,7 +7,6 @@ using Microsoft.Quantum.QsCompiler.CompilationBuilder.DataStructures; using Microsoft.Quantum.QsCompiler.TextProcessing; using Microsoft.VisualStudio.LanguageServer.Protocol; -using Lsp = Microsoft.VisualStudio.LanguageServer.Protocol; using Position = Microsoft.Quantum.QsCompiler.DataTypes.Position; using Range = Microsoft.Quantum.QsCompiler.DataTypes.Range; @@ -24,14 +23,9 @@ internal static class TextProcessor /// For any fragment where the code only consistes of whitespace, /// adds a warning to the returned diagnostics if such a fragment terminates in a semicolon, /// adds an error to the returned diagnostics if it ends in and opening bracket. - /// Throws an ArgumentNullException if the given diagnostics or fragments are null. /// private static IEnumerable CheckForEmptyFragments(this IEnumerable fragments, string filename) { - if (fragments == null) - { - throw new ArgumentNullException(nameof(fragments)); - } // opting to not complain about semicolons not following code anywhere in the file (i.e. on any scope) var diagnostics = fragments.Where(snippet => snippet.Text.Length == 0 && snippet.FollowedBy == ';') .Select(snippet => Warnings.EmptyStatementWarning(filename, snippet.Range.End)) @@ -44,11 +38,10 @@ private static IEnumerable CheckForEmptyFragments(this IEnumerable private static IEnumerable CheckFragmentDelimiters(this CodeFragment fragment, string filename) { - if (fragment?.Kind == null) + if (fragment.Kind == null) { throw new ArgumentException("missing specification of the fragment kind"); } @@ -64,14 +57,9 @@ private static IEnumerable CheckFragmentDelimiters(this CodeFragment /// (i.e. modifies the list of given fragments!). /// Fragments for which the code only consists of whitespace are left unchanged (i.e. the Kind remains set to null). /// Adds a suitable error to the returned diagnostics for each fragment that cannot be processed. - /// Raises an ArgumentNullException if the given diagnostics or fragments are null. /// private static IEnumerable ParseCode(ref List fragments, string filename) { - if (fragments == null) - { - throw new ArgumentNullException(nameof(fragments)); - } var processedFragments = new List(fragments.Count()); var diagnostics = new List(); @@ -204,13 +192,13 @@ private static int StatementStart(this CodeLine line, int start) /// /// Returns the Position after the last character in the file (including comments). - /// Throws an ArgumentNullException is file is null or does not have any content. + /// Throws an ArgumentException is file does not have any content. /// public static Position End(this FileContentManager file) { - if (file == null || file.NrLines() == 0) + if (file.NrLines() == 0) { - throw new ArgumentNullException(nameof(file), "file is null or empty"); + throw new ArgumentException("file is empty", nameof(file)); } return Position.Create(file.NrLines() - 1, file.GetLine(file.NrLines() - 1).Text.Length); } @@ -218,13 +206,13 @@ public static Position End(this FileContentManager file) /// /// Returns the Position right after where the last relevant (i.e. non-comment) code in the file ends, /// or the position (0,0) if no such line exists. - /// Throws an ArgumentNullException if file is null or does not contain any lines. + /// Throws an ArgumentException if file does not contain any lines. /// private static Position LastInFile(FileContentManager file) { - if (file == null || file.NrLines() == 0) + if (file.NrLines() == 0) { - throw new ArgumentNullException(nameof(file), "file is null or missing content"); + throw new ArgumentException("file is null or missing content", nameof(file)); } var endIndex = file.NrLines(); while (endIndex-- > 0 && file.GetLine(endIndex).WithoutEnding.Trim().Length == 0) @@ -240,7 +228,6 @@ private static Position LastInFile(FileContentManager file) /// If the closest previous ending was on the last character in a line, then the returned position is on the same line after the last character. /// Updates the given position to point to the first character in the fragment that contains code. /// Throws an ArgumentException if the given position is not smaller than the position after the last piece of code in the file (given by LastInFile). - /// Throws an ArgumentNullException if any of the arguments is null. /// Throws an ArgumentException if the given position is not within file. /// internal static Position FragmentEnd(this FileContentManager file, ref Position current) @@ -295,7 +282,6 @@ static int MoveNextLine(ref Position position) /// Returns the position right after where the fragment before the one containing the given position ends. /// If the closest previous ending was on the last character in a line, then the returned position is on the same line after the last character. /// If there is no such fragment, returns the position (0,0). - /// Throws an ArgumentNullException if any of the arguments is null. /// Throws an ArgumentException if the given position is not within file. /// private static Position PositionAfterPrevious(this FileContentManager file, Position current) @@ -317,19 +303,10 @@ private static Position PositionAfterPrevious(this FileContentManager file, Posi /// Extracts the code fragments based on the current file content that need to be re-processed due to content changes on the given lines. /// Ignores any whitespace or comments at the beginning of the file (whether they have changed or not). /// Ignores any whitespace or comments that occur after the last piece of code in the file. - /// Throws an ArgumentNullException if any of the arguments is null. /// private static IEnumerable FragmentsToProcess(this FileContentManager file, SortedSet changedLines) { // NOTE: I suggest not to touch this routine unless absolutely necessary...(things *will* break) - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (changedLines == null) - { - throw new ArgumentNullException(nameof(changedLines)); - } var iter = changedLines.GetEnumerator(); var lastInFile = LastInFile(file); @@ -380,15 +357,10 @@ private static IEnumerable FragmentsToProcess(this FileContentMana /// /// Given the start line of a change, and how many lines have been updated from there, /// computes the position where the syntax check will start and end. - /// Throws an ArgumentNullException if file is null. /// Throws an ArgumentOutOfRangeException if the range [start, start + count) is not a valid range within the current file content. /// internal static Range GetSyntaxCheckDelimiters(this FileContentManager file, int start, int count) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } if (start < 0 || start >= file.NrLines()) { throw new ArgumentOutOfRangeException(nameof(start)); @@ -416,15 +388,9 @@ internal static Range GetSyntaxCheckDelimiters(this FileContentManager file, int /// Does nothing if no lines have been modified. /// Recomputes and pushes the syntax diagnostics for the extracted fragments and all end-of-file diagnostics otherwise. /// Processes the extracted fragment and inserts the processed fragments into the corresponding data structure - /// Throws an ArgumentNullException if file is null. /// internal static void UpdateLanguageProcessing(this FileContentManager file) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - file.SyncRoot.EnterUpgradeableReadLock(); try { diff --git a/src/QsCompiler/CompilationManager/TypeChecking.cs b/src/QsCompiler/CompilationManager/TypeChecking.cs index 08b5b85c5c..9311b1ecd9 100644 --- a/src/QsCompiler/CompilationManager/TypeChecking.cs +++ b/src/QsCompiler/CompilationManager/TypeChecking.cs @@ -29,8 +29,6 @@ internal static class TypeChecking /// as well as function that extracts the declaration, builds the corresponding HeaderEntries, /// throwing the corresponding exceptions if the building fails. /// Returns all HeaderEntries for which the extracted name of the declaration is valid. - /// Returns null if the given collection of tokens is null. - /// Throws an ArgumentNullException if the given function for extracting the declaration is null. /// private static IEnumerable<(CodeFragment.TokenIndex, HeaderEntry)> GetHeaderItems( this FileContentManager file, @@ -64,8 +62,6 @@ internal static class TypeChecking /// ignoring any attribute annotations unless ignorePrecedingAttributes is set to false. /// Documenting comments may be separated by an empty lines. /// Strips the preceding triple-slash for the comments, as well as whitespace and the line break at the end. - /// Returns null if no documenting comment is given, or if the documenting comments do not have any non-whitespace content. - /// Throws an ArgumentNullException if the given file or position is null. /// Throws an ArgumentException if the given position is not a valid position within the given file. /// internal static ImmutableArray DocumentingComments(this FileContentManager file, Position pos, bool ignorePrecedingAttributes = true) @@ -173,15 +169,10 @@ internal static ImmutableArray DocumentingComments(this FileContentManag /// /// Given a collection of positioned items, returns the closest proceeding item for the given position. - /// Throws an ArgumentNullException if the given position or collection of items is null. /// Throws an ArgumentException if no item precedes the given position. /// private static T ContainingParent(Position pos, IReadOnlyCollection<(Position, T)> items) { - if (items == null) - { - throw new ArgumentNullException(nameof(items)); - } var preceding = items.TakeWhile(tuple => tuple.Item1 < pos); return preceding.Any() ? preceding.Last().Item2 @@ -192,7 +183,6 @@ private static T ContainingParent(Position pos, IReadOnlyCollection<(Position /// Calls the given function on each of the given items to add, /// and adds the returned diagnostics to the given list of diagnostics. /// Returns a List of the token indices and the corresponding header items for which no errors were generated. - /// Throws an ArgumentNullException if the given diagnostics or items, or the function to add them is null. /// private static List<(TItem, HeaderEntry)> AddItems( IEnumerable<(TItem, HeaderEntry)> itemsToAdd, @@ -200,19 +190,6 @@ private static T ContainingParent(Position pos, IReadOnlyCollection<(Position string fileName, List diagnostics) { - if (itemsToAdd == null) - { - throw new ArgumentNullException(nameof(itemsToAdd)); - } - if (add == null) - { - throw new ArgumentNullException(nameof(add)); - } - if (diagnostics == null) - { - throw new ArgumentNullException(nameof(diagnostics)); - } - var itemsToCompile = new List<(TItem, HeaderEntry)>(); foreach (var (tIndex, headerItem) in itemsToAdd) { @@ -233,7 +210,6 @@ private static T ContainingParent(Position pos, IReadOnlyCollection<(Position /// with either a list of the token indices that contain its specializations to be included in the compilation, /// or a list consisting of the token index of the callable declaration, if the declaration does not contain any specializations. /// Note: This routine assumes that all empty or invalid fragments have been excluded from compilation prior to calling this routine. - /// Throws an ArgumentNullException if any of the given arguments is null. /// Throws an InvalidOperationException if the given file is not at least read-locked, /// since the returned token indices will only be valid until the next write operation that affects the tokens in the file. /// Throws an InvalidOperationException if the lock for the given compilation cannot be set because a dependent lock is the gating lock ("outermost lock"). @@ -241,18 +217,6 @@ private static T ContainingParent(Position pos, IReadOnlyCollection<(Position internal static ImmutableDictionary?)> UpdateGlobalSymbols( this FileContentManager file, CompilationUnit compilation, List diagnostics) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - if (diagnostics == null) - { - throw new ArgumentNullException(nameof(diagnostics)); - } if (!file.SyncRoot.IsAtLeastReadLockHeld()) { throw new InvalidOperationException("file needs to be locked in order to update global symbols"); @@ -329,7 +293,6 @@ private static T ContainingParent(Position pos, IReadOnlyCollection<(Position /// returns a list of the token indices that contain the specializations to be included in the compilation. /// If the given callable does not contain any specializations, /// returns a list of token indices containing only the token of the callable declaration. - /// Throws an ArgumentNullException if either the given namespace or diagnostics are null. /// private static List AddSpecializationsToNamespace( FileContentManager file, @@ -337,14 +300,6 @@ private static T ContainingParent(Position pos, IReadOnlyCollection<(Position (CodeFragment.TokenIndex, HeaderEntry>) parent, List diagnostics) { - if (ns == null) - { - throw new ArgumentNullException(nameof(ns)); - } - if (diagnostics == null) - { - throw new ArgumentNullException(nameof(diagnostics)); - } var contentToCompile = new List(); var callableDecl = parent.Item2.Declaration; var parentName = parent.Item2.PositionedSymbol; @@ -410,19 +365,9 @@ private static T ContainingParent(Position pos, IReadOnlyCollection<(Position /// If no fileName is given or the given fileName is null, /// adds all diagnostics generated during resolution and verification to the given list of diagnostics. /// If the given fileName is not null, adds only the diagnostics for the file with that name to the given list of diagnostics. - /// Throws an ArgumentNullException if the given NamespaceManager or list of diagnostics is null. /// internal static void ResolveGlobalSymbols(NamespaceManager symbols, List diagnostics, string? fileName = null) { - if (symbols == null) - { - throw new ArgumentNullException(nameof(symbols)); - } - if (diagnostics == null) - { - throw new ArgumentNullException(nameof(diagnostics)); - } - var declDiagnostics = symbols.ResolveAll(BuiltIn.NamespacesToAutoOpen); var cycleDiagnostics = SyntaxProcessing.SyntaxTree.CheckDefinedTypesForCycles(symbols.DefinedTypes()); @@ -457,24 +402,10 @@ void AddDiagnostics(NonNullable source, IEnumerable /// Updates the symbol information in the given compilation unit with all (validly placed) open directives in the given file, /// and adds the generated diagnostics for the given file *only* to the given list of diagnostics. - /// Throws an ArgumentNullException if the given compilation unit, the given file or the given diagnostics are null. /// Throws an InvalidOperationException if the lock for the given compilation cannot be set because a dependent lock is the gating lock ("outermost lock"). /// internal static void ImportGlobalSymbols(this FileContentManager file, CompilationUnit compilation, List diagnostics) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - if (diagnostics == null) - { - throw new ArgumentNullException(nameof(diagnostics)); - } - // While in principle the file does not need to be externally locked for this routine to evaluate correctly, // it is to be expected that the file is indeed locked, such that the information about open directives is consistent with the one on header items - // of course there is no way to verify that even if the file is locked, let's still call QsCompilerError.Verify on the file lock. @@ -498,7 +429,6 @@ internal static void ImportGlobalSymbols(this FileContentManager file, Compilati /// /// Builds a FragmentTree containting the given grouping of token indices for a certain parent. /// Assumes that all given token indices are associated with the given file. - /// Throws an ArgumentNullException if the given file or any of the given groupings is null. /// Throws an InvalidOperationException if the given file is not at least read-locked, /// since token indices are only ever valid until the next write operation to the file they are associated with. /// @@ -506,14 +436,6 @@ internal static void ImportGlobalSymbols(this FileContentManager file, Compilati this FileContentManager file, ImmutableDictionary?)> content) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (content == null) - { - throw new ArgumentNullException(nameof(content)); - } if (!file.SyncRoot.IsAtLeastReadLockHeld()) { throw new InvalidOperationException("file needs to be locked in order to build the FragmentTrees from the given token indices"); @@ -548,21 +470,10 @@ internal static void ImportGlobalSymbols(this FileContentManager file, Compilati /// and clears all semantic diagnostics without pushing them. /// If the given Action for publishing diagnostics is not null, /// invokes it for the diagnostics of each given file after updating them. - /// Throws an ArgumentNullException if the given compilation is null, - /// or if the given files, or any file contained in files, is null. /// internal static ImmutableDictionary UpdateGlobalSymbolsFor( this CompilationUnit compilation, IEnumerable files) { - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - if (files == null || files.Contains(null!)) - { - throw new ArgumentNullException(nameof(files)); - } - compilation.EnterWriteLock(); foreach (var file in files) { @@ -613,7 +524,6 @@ internal static void ImportGlobalSymbols(this FileContentManager file, Compilati /// The declarations the scope inherits from its parents are assumed to be the current declarations in the given scope context. /// If a required set of functors are specified, then each operation called within the built scope needs to support these functors. /// If the set of required functors is unspecified or null, then the functors to support are determined by the parent scope. - /// Throws an ArgumentNullException if the given list of tree nodes, scope context or diagnostics are null. /// private static QsScope BuildScope( IReadOnlyList nodeContent, @@ -621,19 +531,6 @@ private static QsScope BuildScope( List diagnostics, ImmutableHashSet? requiredFunctorSupport = null) { - if (nodeContent == null) - { - throw new ArgumentNullException(nameof(nodeContent)); - } - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - if (diagnostics == null) - { - throw new ArgumentNullException(nameof(diagnostics)); - } - var inheritedSymbols = context.Symbols.CurrentDeclarations; context.Symbols.BeginScope(requiredFunctorSupport); var statements = BuildStatements(nodeContent.GetEnumerator(), context, diagnostics); @@ -646,28 +543,12 @@ private static QsScope BuildScope( /// to get the desired object as well as a list of diagnostics. /// Adds the generated diagnostics to the given list of diagnostics, and returns the build object. /// - /// - /// Thrown if the given build function, scope context, or diagnostics are null. - /// private static T BuildStatement( FragmentTree.TreeNode node, Func> build, ScopeContext context, List diagnostics) { - if (build == null) - { - throw new ArgumentNullException(nameof(build)); - } - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - if (diagnostics == null) - { - throw new ArgumentNullException(nameof(diagnostics)); - } - var statementPos = node.Fragment.Range.Start; var location = new QsLocation(node.RelativePosition, node.Fragment.HeaderRange); var (statement, messages) = build(location, context); @@ -686,7 +567,6 @@ private static T BuildStatement( /// i.e. it is set to true if either the iterator has not been moved (no statement built), /// or if the last MoveNext() returned true, and is otherwise set to false. /// This routine will fail if accessing the current iterator item fails. - /// Throws an ArgumentNullException if any of the given arguments is null. /// Throws an ArgumentException if the given scope context does not currently contain an open scope. /// private static bool TryBuildUsingStatement( @@ -696,22 +576,10 @@ private static bool TryBuildUsingStatement( out bool proceed, [NotNullWhen(true)] out QsStatement? statement) { - if (nodes == null) - { - throw new ArgumentNullException(nameof(nodes)); - } - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } if (context.Symbols.AllScopesClosed) { throw new ArgumentException("invalid scope context state - statements may only occur within a scope"); } - if (diagnostics == null) - { - throw new ArgumentException(nameof(diagnostics)); - } if (nodes.Current.Fragment.Kind is QsFragmentKind.UsingBlockIntro allocate) { @@ -742,7 +610,6 @@ private static bool TryBuildUsingStatement( /// i.e. it is set to true if either the iterator has not been moved (no statement built), /// or if the last MoveNext() returned true, and is otherwise set to false. /// This routine will fail if accessing the current iterator item fails. - /// Throws an ArgumentNullException if any of the given arguments is null. /// Throws an ArgumentException if the given scope context does not currently contain an open scope. /// private static bool TryBuildBorrowStatement( @@ -752,22 +619,10 @@ private static bool TryBuildBorrowStatement( out bool proceed, [NotNullWhen(true)] out QsStatement? statement) { - if (nodes == null) - { - throw new ArgumentNullException(nameof(nodes)); - } - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } if (context.Symbols.AllScopesClosed) { throw new ArgumentException("invalid scope context state - statements may only occur within a scope"); } - if (diagnostics == null) - { - throw new ArgumentException(nameof(diagnostics)); - } if (nodes.Current.Fragment.Kind is QsFragmentKind.BorrowingBlockIntro borrow) { @@ -798,7 +653,6 @@ private static bool TryBuildBorrowStatement( /// i.e. it is set to true if either the iterator has not been moved (no statement built), /// or if the last MoveNext() returned true, and is otherwise set to false. /// This routine will fail if accessing the current iterator item fails. - /// Throws an ArgumentNullException if any of the given arguments is null. /// Throws an ArgumentException if the given scope context does not currently contain an open scope, /// or if the repeat header is not followed by a until-success clause. /// @@ -809,22 +663,10 @@ private static bool TryBuildRepeatStatement( out bool proceed, [NotNullWhen(true)] out QsStatement? statement) { - if (nodes == null) - { - throw new ArgumentNullException(nameof(nodes)); - } - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } if (context.Symbols.AllScopesClosed) { throw new ArgumentException("invalid scope context state - statements may only occur within a scope"); } - if (diagnostics == null) - { - throw new ArgumentException(nameof(diagnostics)); - } if (nodes.Current.Fragment.Kind?.IsRepeatIntro ?? false) { @@ -879,7 +721,6 @@ private static bool TryBuildRepeatStatement( /// i.e. it is set to true if either the iterator has not been moved (no statement built), /// or if the last MoveNext() returned true, and is otherwise set to false. /// This routine will fail if accessing the current iterator item fails. - /// Throws an ArgumentNullException if any of the given arguments is null. /// Throws an ArgumentException if the given scope context does not currently contain an open scope. /// private static bool TryBuildForStatement( @@ -889,22 +730,10 @@ private static bool TryBuildForStatement( out bool proceed, [NotNullWhen(true)] out QsStatement? statement) { - if (nodes == null) - { - throw new ArgumentNullException(nameof(nodes)); - } - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } if (context.Symbols.AllScopesClosed) { throw new ArgumentException("invalid scope context state - statements may only occur within a scope"); } - if (diagnostics == null) - { - throw new ArgumentException(nameof(diagnostics)); - } if (nodes.Current.Fragment.Kind is QsFragmentKind.ForLoopIntro forStatement) { @@ -935,7 +764,6 @@ private static bool TryBuildForStatement( /// i.e. it is set to true if either the iterator has not been moved (no statement built), /// or if the last MoveNext() returned true, and is otherwise set to false. /// This routine will fail if accessing the current iterator item fails. - /// Throws an ArgumentNullException if any of the given arguments is null. /// Throws an ArgumentException if the given scope context does not currently contain an open scope. /// private static bool TryBuildWhileStatement( @@ -945,22 +773,10 @@ private static bool TryBuildWhileStatement( out bool proceed, [NotNullWhen(true)] out QsStatement? statement) { - if (nodes == null) - { - throw new ArgumentNullException(nameof(nodes)); - } - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } if (context.Symbols.AllScopesClosed) { throw new ArgumentException("invalid scope context state - statements may only occur within a scope"); } - if (diagnostics == null) - { - throw new ArgumentException(nameof(diagnostics)); - } if (nodes.Current.Fragment.Kind is QsFragmentKind.WhileLoopIntro whileStatement) { @@ -991,7 +807,6 @@ private static bool TryBuildWhileStatement( /// i.e. it is set to true if either the iterator has not been moved (no statement built), /// or if the last MoveNext() returned true, and is otherwise set to false. /// This routine will fail if accessing the current iterator item fails. - /// Throws an ArgumentNullException if any of the given arguments is null. /// Throws an ArgumentException if the given scope context does not currently contain an open scope. /// private static bool TryBuildIfStatement( @@ -1001,22 +816,10 @@ private static bool TryBuildIfStatement( out bool proceed, [NotNullWhen(true)] out QsStatement? statement) { - if (nodes == null) - { - throw new ArgumentNullException(nameof(nodes)); - } - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } if (context.Symbols.AllScopesClosed) { throw new ArgumentException("invalid scope context state - statements may only occur within a scope"); } - if (diagnostics == null) - { - throw new ArgumentException(nameof(diagnostics)); - } if (nodes.Current.Fragment.Kind is QsFragmentKind.IfClause ifCond) { @@ -1077,7 +880,6 @@ private static bool TryBuildIfStatement( /// i.e. it is set to true if either the iterator has not been moved (no statement built), /// or if the last MoveNext() returned true, and is otherwise set to false. /// This routine will fail if accessing the current iterator item fails. - /// Throws an ArgumentNullException if any of the given arguments is null. /// Throws an ArgumentException if the given scope context does not currently contain an open scope. /// private static bool TryBuildConjugationStatement( @@ -1087,22 +889,10 @@ private static bool TryBuildConjugationStatement( out bool proceed, [NotNullWhen(true)] out QsStatement? statement) { - if (nodes == null) - { - throw new ArgumentNullException(nameof(nodes)); - } - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } if (context.Symbols.AllScopesClosed) { throw new ArgumentException("invalid scope context state - statements may only occur within a scope"); } - if (diagnostics == null) - { - throw new ArgumentException(nameof(diagnostics)); - } QsNullable RelativeLocation(FragmentTree.TreeNode node) => QsNullable.NewValue(new QsLocation(node.RelativePosition, node.Fragment.HeaderRange)); @@ -1147,7 +937,6 @@ QsNullable RelativeLocation(FragmentTree.TreeNode node) => /// i.e. it is set to true if either the iterator has not been moved (no statement built), /// or if the last MoveNext() returned true, and is otherwise set to false. /// This routine will fail if accessing the current iterator item fails. - /// Throws an ArgumentNullException if any of the given arguments is null. /// Throws an ArgumentException if the given scope context does not currently contain an open scope. /// private static bool TryBuildLetStatement( @@ -1157,22 +946,10 @@ private static bool TryBuildLetStatement( out bool proceed, [NotNullWhen(true)] out QsStatement? statement) { - if (nodes == null) - { - throw new ArgumentNullException(nameof(nodes)); - } - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } if (context.Symbols.AllScopesClosed) { throw new ArgumentException("invalid scope context state - statements may only occur within a scope"); } - if (diagnostics == null) - { - throw new ArgumentException(nameof(diagnostics)); - } if (nodes.Current.Fragment.Kind is QsFragmentKind.ImmutableBinding letStatement) { @@ -1199,7 +976,6 @@ private static bool TryBuildLetStatement( /// i.e. it is set to true if either the iterator has not been moved (no statement built), /// or if the last MoveNext() returned true, and is otherwise set to false. /// This routine will fail if accessing the current iterator item fails. - /// Throws an ArgumentNullException if any of the given arguments is null. /// Throws an ArgumentException if the given scope context does not currently contain an open scope. /// private static bool TryBuildMutableStatement( @@ -1209,22 +985,10 @@ private static bool TryBuildMutableStatement( out bool proceed, [NotNullWhen(true)] out QsStatement? statement) { - if (nodes == null) - { - throw new ArgumentNullException(nameof(nodes)); - } - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } if (context.Symbols.AllScopesClosed) { throw new ArgumentException("invalid scope context state - statements may only occur within a scope"); } - if (diagnostics == null) - { - throw new ArgumentException(nameof(diagnostics)); - } if (nodes.Current.Fragment.Kind is QsFragmentKind.MutableBinding mutableStatement) { @@ -1251,7 +1015,6 @@ private static bool TryBuildMutableStatement( /// i.e. it is set to true if either the iterator has not been moved (no statement built), /// or if the last MoveNext() returned true, and is otherwise set to false. /// This routine will fail if accessing the current iterator item fails. - /// Throws an ArgumentNullException if any of the given arguments is null. /// Throws an ArgumentException if the given scope context does not currently contain an open scope. /// private static bool TryBuildSetStatement( @@ -1261,22 +1024,10 @@ private static bool TryBuildSetStatement( out bool proceed, [NotNullWhen(true)] out QsStatement? statement) { - if (nodes == null) - { - throw new ArgumentNullException(nameof(nodes)); - } - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } if (context.Symbols.AllScopesClosed) { throw new ArgumentException("invalid scope context state - statements may only occur within a scope"); } - if (diagnostics == null) - { - throw new ArgumentException(nameof(diagnostics)); - } if (nodes.Current.Fragment.Kind is QsFragmentKind.ValueUpdate setStatement) { @@ -1303,7 +1054,6 @@ private static bool TryBuildSetStatement( /// i.e. it is set to true if either the iterator has not been moved (no statement built), /// or if the last MoveNext() returned true, and is otherwise set to false. /// This routine will fail if accessing the current iterator item fails. - /// Throws an ArgumentNullException if any of the given arguments is null. /// Throws an ArgumentException if the given scope context does not currently contain an open scope. /// private static bool TryBuildFailStatement( @@ -1313,22 +1063,10 @@ private static bool TryBuildFailStatement( out bool proceed, [NotNullWhen(true)] out QsStatement? statement) { - if (nodes == null) - { - throw new ArgumentNullException(nameof(nodes)); - } - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } if (context.Symbols.AllScopesClosed) { throw new ArgumentException("invalid scope context state - statements may only occur within a scope"); } - if (diagnostics == null) - { - throw new ArgumentException(nameof(diagnostics)); - } if (nodes.Current.Fragment.Kind is QsFragmentKind.FailStatement failStatement) { @@ -1355,7 +1093,6 @@ private static bool TryBuildFailStatement( /// i.e. it is set to true if either the iterator has not been moved (no statement built), /// or if the last MoveNext() returned true, and is otherwise set to false. /// This routine will fail if accessing the current iterator item fails. - /// Throws an ArgumentNullException if any of the given arguments is null. /// Throws an ArgumentException if the given scope context does not currently contain an open scope. /// private static bool TryBuildReturnStatement( @@ -1365,22 +1102,10 @@ private static bool TryBuildReturnStatement( out bool proceed, [NotNullWhen(true)] out QsStatement? statement) { - if (nodes == null) - { - throw new ArgumentNullException(nameof(nodes)); - } - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } if (context.Symbols.AllScopesClosed) { throw new ArgumentException("invalid scope context state - statements may only occur within a scope"); } - if (diagnostics == null) - { - throw new ArgumentException(nameof(diagnostics)); - } if (nodes.Current.Fragment.Kind is QsFragmentKind.ReturnStatement returnStatement) { @@ -1407,7 +1132,6 @@ private static bool TryBuildReturnStatement( /// i.e. it is set to true if either the iterator has not been moved (no statement built), /// or if the last MoveNext() returned true, and is otherwise set to false. /// This routine will fail if accessing the current iterator item fails. - /// Throws an ArgumentNullException if any of the given arguments is null. /// Throws an ArgumentException if the given scope context does not currently contain an open scope. /// private static bool TryBuildExpressionStatement( @@ -1417,22 +1141,10 @@ private static bool TryBuildExpressionStatement( out bool proceed, [NotNullWhen(true)] out QsStatement? statement) { - if (nodes == null) - { - throw new ArgumentNullException(nameof(nodes)); - } - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } if (context.Symbols.AllScopesClosed) { throw new ArgumentException("invalid scope context state - statements may only occur within a scope"); } - if (diagnostics == null) - { - throw new ArgumentException(nameof(diagnostics)); - } if (nodes.Current.Fragment.Kind is QsFragmentKind.ExpressionStatement expressionStatement) { @@ -1454,36 +1166,23 @@ private static bool TryBuildExpressionStatement( /// provided each statement consists of a suitable statement header followed by the required continuation(s), if any. /// Throws an ArgumentException if this is not the case, /// or if the given scope context does not currently contain an open scope. - /// Throws an ArgumentNullException if any of the given arguments is null, /// or if any of the fragments contained in the given nodes is null. /// private static ImmutableArray BuildStatements( IEnumerator nodes, ScopeContext context, List diagnostics) { - if (nodes == null) - { - throw new ArgumentNullException(nameof(nodes)); - } - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } if (context.Symbols.AllScopesClosed) { throw new ArgumentException("invalid scope context state - statements may only occur within a scope"); } - if (diagnostics == null) - { - throw new ArgumentException(nameof(diagnostics)); - } var proceed = nodes.MoveNext(); var statements = new List(); while (proceed) { - if (nodes.Current.Fragment?.Kind == null) + if (nodes.Current.Fragment.Kind == null) { - throw new ArgumentNullException(nameof(nodes.Current.Fragment), "fragment kind cannot be null"); + throw new ArgumentException("fragment kind cannot be null", nameof(nodes.Current.Fragment)); } else if (TryBuildExpressionStatement(nodes, context, diagnostics, out proceed, out var expressionStatement)) { @@ -1557,7 +1256,6 @@ private static ImmutableArray BuildStatements( /// for argument variables defined in the callable declaration). /// If the expected return type for the specialization is not Unit, verifies that all paths return a value or fail, generating suitable diagnostics. /// Adds the generated diagnostics to the given list of diagnostics. - /// Throws an ArgumentNullException if the given argument, the scope context, or diagnostics are null. /// private static SpecializationImplementation BuildUserDefinedImplementation( FragmentTree.TreeNode root, @@ -1567,23 +1265,6 @@ private static SpecializationImplementation BuildUserDefinedImplementation( ScopeContext context, List diagnostics) { - if (argTuple == null) - { - throw new ArgumentNullException(nameof(argTuple)); - } - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - if (requiredFunctorSupport == null) - { - throw new ArgumentNullException(nameof(requiredFunctorSupport)); - } - if (diagnostics == null) - { - throw new ArgumentNullException(nameof(diagnostics)); - } - // the variable defined on the declaration need to be verified upon building the callable (otherwise we get duplicate diagnostics), // but they need to be pushed *first* such that we get suitable re-declaration errors on those defined on the specialization // -> the position information is set to null (only) for variables defined in the declaration @@ -1622,22 +1303,11 @@ private static SpecializationImplementation BuildUserDefinedImplementation( /// /// Given a function that returns the generator directive for a given specialization kind, or null if none has been defined for that kind, /// determines the necessary functor support required for each operation call within a user defined implementation of the specified specialization. - /// Throws an ArgumentNullException if the given specialization for which to determine the required functor support is null, - /// or if the given function to query the directives is. /// private static IEnumerable RequiredFunctorSupport( QsSpecializationKind spec, Func directives) { - if (spec == null) - { - throw new ArgumentNullException(nameof(spec)); - } - if (directives == null) - { - throw new ArgumentNullException(nameof(directives)); - } - var adjDir = directives(QsSpecializationKind.QsAdjoint); var ctlDir = directives(QsSpecializationKind.QsControlled); var ctlAdjDir = directives(QsSpecializationKind.QsControlledAdjoint); @@ -1697,8 +1367,6 @@ private static IEnumerable RequiredFunctorSupport( /// If the given root is a callable declaration, a default body specialization with its children as the implementation is returned - /// provided the children are exclusively valid statements. Fails with the corresponding exception otherwise. /// Adds the generated diagnostics to the given list of diagnostics. - /// Throws an ArgumentNullException if the parent signature, its argument tuple, - /// the compilation unit, or the given list of diagnostics is null. /// Throws an ArgumentException if the given root is neither a specialization declaration, nor a callable declaration, /// or if the callable the specialization belongs to does not support that specialization according to the given NamespaceManager. /// @@ -1710,22 +1378,6 @@ private static ImmutableArray BuildSpecializations( List diagnostics, CancellationToken cancellationToken) { - if (parentSignature == null) - { - throw new ArgumentNullException(nameof(parentSignature)); - } - if (argTuple == null) - { - throw new ArgumentNullException(nameof(argTuple)); - } - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - if (diagnostics == null) - { - throw new ArgumentNullException(nameof(diagnostics)); - } if (cancellationToken.IsCancellationRequested) { return ImmutableArray.Empty; @@ -1910,26 +1562,12 @@ bool InvalidCharacteristicsOrSupportedFunctors(params QsFunctor[] functors) => /// For each namespace and callable name that occurs in the given FragmentTrees builds the corresponding QsCallable. /// Updates the given CompilationUnit with all built callables. Checks all types defined in the NamespaceManager for cycles. /// Returns a list with all accumulated diagnostics. If the request has been cancelled, returns null. - /// Throws an ArgumentNullException if any of the arguments is null. /// internal static List? RunTypeChecking( CompilationUnit compilation, ImmutableDictionary roots, CancellationToken cancellationToken) { - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - if (roots == null) - { - throw new ArgumentNullException(nameof(roots)); - } - if (cancellationToken == null) - { - throw new ArgumentNullException(nameof(cancellationToken)); - } - var diagnostics = new List(); compilation.EnterUpgradeableReadLock(); try @@ -2051,11 +1689,6 @@ bool InvalidCharacteristicsOrSupportedFunctors(params QsFunctor[] functors) => private static (LocalDeclarations, IEnumerable) StatementsAfterAndLocalDeclarationsAt( this QsScope scope, Position relativePosition, bool includeDeclaredAtPosition) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } - LocalDeclarations Concat(LocalDeclarations fst, LocalDeclarations snd) => new LocalDeclarations(fst.Variables.Concat(snd.Variables).ToImmutableArray()); bool BeforePosition(QsNullable location) => @@ -2171,19 +1804,9 @@ public static LocalDeclarations LocalDeclarationsAt(this QsScope scope, Position /// directly proceeds to do the type checking for the entire file content, independent on what parts have been changed. /// If the globally declared types/callables have changed, a global type checking event is triggered, /// since the type checking for the entire compilation unit and all compilation units depending on it needs to be recomputed. - /// Throws an ArgumentNullException if the given file or compilation unit is null. /// internal static void UpdateTypeChecking(this FileContentManager file, CompilationUnit compilation) { - if (file == null) - { - throw new ArgumentNullException(nameof(file)); - } - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - compilation.EnterWriteLock(); file.SyncRoot.EnterUpgradeableReadLock(); try diff --git a/src/QsCompiler/CompilationManager/Utils.cs b/src/QsCompiler/CompilationManager/Utils.cs index 0ff8d76bdb..712eac6ebb 100644 --- a/src/QsCompiler/CompilationManager/Utils.cs +++ b/src/QsCompiler/CompilationManager/Utils.cs @@ -102,20 +102,15 @@ public static string[] SplitLines(string text) /// /// Given a string, replaces the range [starChar, endChar) with the given string to insert. /// Returns null if the given text is null. - /// Throws an ArgumentNullException if the given text to insert is null. /// Throws an ArgumentOutOfRangeException if the given start and end points do not denote a valid range within the string. /// [return: NotNullIfNotNull("lineText")] - internal static string? GetChangedText(string lineText, int startChar, int endChar, string insert) + internal static string? GetChangedText(string? lineText, int startChar, int endChar, string insert) { if (lineText == null) { return null; } - if (insert == null) - { - throw new ArgumentNullException(nameof(insert)); - } if (startChar < 0 || startChar > lineText.Length) { throw new ArgumentOutOfRangeException(nameof(startChar)); @@ -128,20 +123,17 @@ public static string[] SplitLines(string text) } /// - /// Return a string with the new content of the (entire) lines in the range [start, end] where start and end are the start and end line of the given change. - /// Verifies that the given change is consistent with the given file - i.e. the range is a valid range in file, and the text is not null, and - /// throws the correspoding exceptions if this is not the case. + /// Return a string with the new content of the (entire) lines in the range [start, end] where start and end are + /// the start and end line of the given change. /// + /// Thrown if the range is invalid. + /// Thrown if the range is not contained in the file. internal static string GetTextChangedLines(FileContentManager file, TextDocumentContentChangeEvent change) { if (!file.ContainsRange(change.Range.ToQSharp())) { throw new ArgumentOutOfRangeException(nameof(change)); // range can be empty } - if (change.Text == null) - { - throw new ArgumentNullException(nameof(change.Text), "the given text change is null"); - } var first = file.GetLine(change.Range.Start.Line).Text; var last = file.GetLine(change.Range.End.Line).Text; @@ -154,111 +146,55 @@ internal static string GetTextChangedLines(FileContentManager file, TextDocument /// /// Partitions the given IEnumerable into the elements for which predicate returns true and those for which it returns false. - /// Throws an ArgumentNullException if the given IEnumerable or predicate is null. /// - public static (List, List) Partition(this IEnumerable collection, Func predicate) - { - if (collection is null) - { - throw new ArgumentNullException(nameof(collection)); - } - if (predicate == null) - { - throw new ArgumentNullException(nameof(predicate)); - } - return (collection.Where(predicate).ToList(), collection.Where(x => !predicate(x)).ToList()); - } + public static (List, List) Partition(this IEnumerable collection, Func predicate) => + (collection.Where(predicate).ToList(), collection.Where(x => !predicate(x)).ToList()); /// /// Returns true if the given lock is either ReadLockHeld, or is UpgradeableReadLockHeld, or isWriteLockHeld. - /// Throws an ArgumentNullException if the given lock is null. /// - public static bool IsAtLeastReadLockHeld(this ReaderWriterLockSlim syncRoot) - { - if (syncRoot == null) - { - throw new ArgumentNullException(nameof(syncRoot)); - } - return syncRoot.IsReadLockHeld || syncRoot.IsUpgradeableReadLockHeld || syncRoot.IsWriteLockHeld; - } + public static bool IsAtLeastReadLockHeld(this ReaderWriterLockSlim syncRoot) => + syncRoot.IsReadLockHeld || syncRoot.IsUpgradeableReadLockHeld || syncRoot.IsWriteLockHeld; // utils for dealing with positions and ranges /// /// Converts the language server protocol position into a Q# compiler position. /// - /// Thrown if is null. /// Thrown if is invalid. public static Position ToQSharp(this Lsp.Position position) => - position is null - ? throw new ArgumentNullException(nameof(position)) - : Position.Create(position.Line, position.Character); + Position.Create(position.Line, position.Character); /// /// Converts the Q# compiler position into a language server protocol position. /// - /// Thrown if is null. public static Lsp.Position ToLsp(this Position position) => - position is null - ? throw new ArgumentNullException(nameof(position)) - : new Lsp.Position(position.Line, position.Column); + new Lsp.Position(position.Line, position.Column); /// /// Converts the language server protocol range into a Q# compiler range. /// - /// Thrown if is null. /// Thrown if is invalid. public static Range ToQSharp(this Lsp.Range range) => - range is null - ? throw new ArgumentNullException(nameof(range)) - : Range.Create(range.Start.ToQSharp(), range.End.ToQSharp()); + Range.Create(range.Start.ToQSharp(), range.End.ToQSharp()); /// /// Converts the Q# compiler range into a language server protocol range. /// - /// Thrown if is null. public static Lsp.Range ToLsp(this Range range) => - range is null - ? throw new ArgumentNullException(nameof(range)) - : new Lsp.Range { Start = range.Start.ToLsp(), End = range.End.ToLsp() }; + new Lsp.Range { Start = range.Start.ToLsp(), End = range.End.ToLsp() }; /// /// Returns true if the position is within the bounds of the file contents. /// - /// - /// Thrown if or is null. - /// - internal static bool ContainsPosition(this FileContentManager file, Position position) - { - if (file is null) - { - throw new ArgumentNullException(nameof(file)); - } - if (position is null) - { - throw new ArgumentNullException(nameof(position)); - } - return position.Line < file.NrLines() && position.Column <= file.GetLine(position.Line).Text.Length; - } + internal static bool ContainsPosition(this FileContentManager file, Position position) => + position.Line < file.NrLines() && position.Column <= file.GetLine(position.Line).Text.Length; /// /// Returns true if the range is within the bounds of the file contents. /// - /// - /// Thrown if or is null. - /// - internal static bool ContainsRange(this FileContentManager file, Range range) - { - if (file is null) - { - throw new ArgumentNullException(nameof(file)); - } - if (range is null) - { - throw new ArgumentNullException(nameof(range)); - } - return file.ContainsPosition(range.Start) && file.ContainsPosition(range.End) && range.Start <= range.End; - } + internal static bool ContainsRange(this FileContentManager file, Range range) => + file.ContainsPosition(range.Start) && file.ContainsPosition(range.End) && range.Start <= range.End; // tools for debugging diff --git a/src/QsCompiler/Compiler/CompilationLoader.cs b/src/QsCompiler/Compiler/CompilationLoader.cs index de98c2002d..67e5c5ee53 100644 --- a/src/QsCompiler/Compiler/CompilationLoader.cs +++ b/src/QsCompiler/Compiler/CompilationLoader.cs @@ -144,7 +144,7 @@ public struct Configuration /// If the output folder is not null, /// documentation is generated in the specified folder based on doc comments in the source code. /// - public string DocumentationOutputFolder; + public string? DocumentationOutputFolder; /// /// Directory where the compiled binaries will be generated. @@ -175,7 +175,7 @@ public struct Configuration /// (i.e. classes implementing IRewriteStep) and the corresponding output folder. /// The contained rewrite steps will be executed in the defined order and priority at the end of the compilation. /// - public IEnumerable<(string, string?)> RewriteSteps; + public IEnumerable<(string, string?)>? RewriteSteps; /// /// If set to true, the post-condition for loaded rewrite steps is checked if the corresponding verification is implemented. @@ -189,14 +189,14 @@ public struct Configuration /// However, the compiler may overwrite the assembly constants defined for the Q# compilation unit in the dictionary of the loaded step. /// The given dictionary in this configuration is left unchanged in any case. /// - public IReadOnlyDictionary AssemblyConstants; + public IReadOnlyDictionary? AssemblyConstants; /// /// Paths to the assemblies that contains a syntax tree with target specific implementations for certain functions and operations. /// The functions and operations defined in these assemblies replace the ones declared within the compilation unit. /// If no paths are specified here or the sequence is null then this compilation step is omitted. /// - public IEnumerable TargetPackageAssemblies; + public IEnumerable? TargetPackageAssemblies; /// /// Indicates whether a serialization of the syntax tree needs to be generated. @@ -452,7 +452,6 @@ public Status LoadedRewriteStep(string name, string? source = null) /// Builds the compilation for the source files and references loaded by the given loaders, /// executing the compilation steps specified by the given options. /// Uses the specified logger to log all diagnostic events. - /// Throws an ArgumentNullException if either one of the given loaders is null or returns null. /// public CompilationLoader(SourceLoader loadSources, ReferenceLoader loadReferences, Configuration? options = null, ILogger? logger = null) { @@ -474,16 +473,14 @@ public CompilationLoader(SourceLoader loadSources, ReferenceLoader loadReference this.compilationStatus.PluginLoading = rewriteStepLoading; this.RaiseCompilationTaskStart("OverallCompilation", "SourcesLoading"); - var sourceFiles = loadSources?.Invoke(this.LoadSourceFiles) - ?? throw new ArgumentNullException("unable to load source files"); + var sourceFiles = loadSources(this.LoadSourceFiles); this.RaiseCompilationTaskEnd("OverallCompilation", "SourcesLoading"); this.RaiseCompilationTaskStart("OverallCompilation", "ReferenceLoading"); - var references = loadReferences?.Invoke( + var references = loadReferences( refs => this.LoadAssemblies( refs, loadTestNames: this.config.ExposeReferencesViaTestNames, - ignoreDllResources: this.config.LoadReferencesBasedOnGeneratedCsharp)) - ?? throw new ArgumentNullException("unable to load referenced binary files"); + ignoreDllResources: this.config.LoadReferencesBasedOnGeneratedCsharp)); this.RaiseCompilationTaskEnd("OverallCompilation", "ReferenceLoading"); // building the compilation @@ -530,7 +527,10 @@ public CompilationLoader(SourceLoader loadSources, ReferenceLoader loadReference if (this.config.LoadTargetSpecificDecompositions) { this.RaiseCompilationTaskStart("Build", "ReplaceTargetSpecificImplementations"); - this.CompilationOutput = this.ReplaceTargetSpecificImplementations(this.config.TargetPackageAssemblies, thisDllUri, references.Declarations.Count); + this.CompilationOutput = this.ReplaceTargetSpecificImplementations( + this.config.TargetPackageAssemblies ?? Enumerable.Empty(), + thisDllUri, + references.Declarations.Count); this.RaiseCompilationTaskEnd("Build", "ReplaceTargetSpecificImplementations"); } @@ -641,7 +641,6 @@ public CompilationLoader(IEnumerable sources, IEnumerable refere /// Builds the compilation of the specified source files and the loaded references returned by the given loader, /// executing the compilation steps specified by the given options. /// Uses the specified logger to log all diagnostic events. - /// Throws an ArgumentNullException if the given loader is null or returns null. /// public CompilationLoader(IEnumerable sources, ReferenceLoader loadReferences, Configuration? options = null, ILogger? logger = null) : this(load => load(sources), loadReferences, options, logger) @@ -652,7 +651,6 @@ public CompilationLoader(IEnumerable sources, ReferenceLoader loadRefere /// Builds the compilation of the content returned by the given loader and the specified references, /// executing the compilation steps specified by the given options. /// Uses the specified logger to log all diagnostic events. - /// Throws an ArgumentNullException if the given loader is null or returns null. /// public CompilationLoader(SourceLoader loadSources, IEnumerable references, Configuration? options = null, ILogger? logger = null) : this(loadSources, load => load(references), options, logger) @@ -663,7 +661,6 @@ public CompilationLoader(SourceLoader loadSources, IEnumerable reference /// /// Logs the given diagnostic and updates the status passed as reference accordingly. - /// Throws an ArgumentNullException if the given diagnostic is null. /// private void LogAndUpdate(ref Status current, Diagnostic d) { @@ -695,7 +692,6 @@ private void LogAndUpdate(ref Status current, ErrorCode code, IEnumerable /// Logs the given diagnostic and updates the status passed as reference accordingly. /// Adds the given diagnostic to the tracked load diagnostics. - /// Throws an ArgumentNullException if the given diagnostic is null. /// private void LogAndUpdateLoadDiagnostics(ref Status current, Diagnostic d) { @@ -718,10 +714,6 @@ private void OnCompilerException(Exception ex) /// private void PrintResolvedFiles(IEnumerable sourceFiles) { - if (sourceFiles == null) - { - return; - } var args = sourceFiles.Any() ? sourceFiles.Select(f => f.LocalPath).ToArray() : new string[] { "(none)" }; @@ -775,13 +767,14 @@ private void RaiseCompilationTaskEnd(string? parentTaskName, string taskName) => CompilationTaskEvent?.Invoke(this, new CompilationTaskEventArgs(CompilationTaskEventType.End, parentTaskName, taskName)); /// - /// Executes the given rewrite step on the current CompilationOutput, and updates the given status accordingly. - /// Sets the CompilationOutput to the transformed compilation if the status indicates success. + /// Executes the given rewrite step on the current CompilationOutput if it is valid, and updates the given + /// status accordingly. Sets the CompilationOutput to the transformed compilation if the status indicates + /// success. /// private QsCompilation? ExecuteAsAtomicTransformation(RewriteSteps.LoadedStep rewriteStep, ref Status status) { QsCompilation? transformed = null; - if (this.compilationStatus.Validation != Status.Succeeded) + if (this.CompilationOutput is null || this.compilationStatus.Validation != Status.Succeeded) { status = Status.NotRun; } @@ -794,20 +787,14 @@ private void RaiseCompilationTaskEnd(string? parentTaskName, string taskName) => /// /// Attempts to load the target package assemblies with the given paths, logging diagnostics - /// when a path is null or invalid, or loading fails. Logs suitable diagnostics if the loaded dlls + /// when a path is invalid, or loading fails. Logs suitable diagnostics if the loaded dlls /// contains conflicting declarations. Updates the compilation status accordingly. /// Executes the transformation to replace target specific implementations as atomic rewrite step. /// Returns the transformed compilation if all assemblies have been successfully loaded and combined. /// Returns the unmodified CompilationOutput otherwise. - /// Throws an ArgumentNullException if the given sequence of paths is null. /// private QsCompilation? ReplaceTargetSpecificImplementations(IEnumerable paths, Uri rewriteStepOrigin, int nrReferences) { - if (paths == null) - { - throw new ArgumentNullException(nameof(paths)); - } - void LogError(ErrorCode errCode, string[] args) => this.LogAndUpdate(ref this.compilationStatus.TargetSpecificReplacements, errCode, args); void LogException(Exception ex) => this.LogAndUpdate(ref this.compilationStatus.TargetSpecificReplacements, ex); @@ -846,19 +833,9 @@ private void RaiseCompilationTaskEnd(string? parentTaskName, string taskName) => /// /// Executes the given rewrite step on the given compilation, returning a transformed compilation as an out parameter. /// Catches and logs any thrown exception. Returns the status of the rewrite step. - /// Throws an ArgumentNullException if the rewrite step to execute or the given compilation is null. /// - private Status ExecuteRewriteStep(RewriteSteps.LoadedStep rewriteStep, QsCompilation? compilation, out QsCompilation? transformed) + private Status ExecuteRewriteStep(RewriteSteps.LoadedStep rewriteStep, QsCompilation compilation, out QsCompilation? transformed) { - if (rewriteStep == null) - { - throw new ArgumentNullException(nameof(rewriteStep)); - } - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } - string? GetDiagnosticsCode(DiagnosticSeverity severity) => rewriteStep.Name == "CsharpGeneration" && severity == DiagnosticSeverity.Error ? Errors.Code(ErrorCode.CsharpGenerationGeneratedError) : rewriteStep.Name == "CsharpGeneration" && severity == DiagnosticSeverity.Warning ? Warnings.Code(WarningCode.CsharpGenerationGeneratedWarning) : @@ -976,17 +953,12 @@ private References LoadAssemblies(IEnumerable refs, bool loadTestNames, /// Logs suitable diagnostics in the process and modifies the compilation status accordingly. /// Does *not* close the given memory stream, and /// returns true if the serialization has been successfully generated. - /// Throws an ArgumentNullException if the given memory stream is null. /// private bool SerializeSyntaxTree(MemoryStream ms) { void LogError() => this.LogAndUpdate( ref this.compilationStatus.Serialization, ErrorCode.SerializationFailed, Enumerable.Empty()); - if (ms == null) - { - throw new ArgumentNullException(nameof(ms)); - } this.compilationStatus.Serialization = 0; if (this.CompilationOutput == null) { @@ -1018,14 +990,9 @@ void LogError() => this.LogAndUpdate( /// Returns the absolute path of the file where the binary representation has been generated. /// Returns null if the binary file could not be generated. /// Does *not* close the given memory stream. - /// Throws an ArgumentNullException if the given memory stream is null. /// private string? GenerateBinary(MemoryStream serialization) { - if (serialization == null) - { - throw new ArgumentNullException(nameof(serialization)); - } this.compilationStatus.BinaryFormat = 0; var projId = NonNullable.New(Path.GetFullPath(this.config.ProjectNameWithExtension ?? Path.GetRandomFileName())); @@ -1057,14 +1024,9 @@ void LogError() => this.LogAndUpdate( /// Returns the absolute path of the file where the dll has been generated. /// Returns null if the dll could not be generated. /// Does *not* close the given memory stream. - /// Throws an ArgumentNullException if the given memory stream is null. /// private string? GenerateDll(MemoryStream serialization) { - if (serialization == null) - { - throw new ArgumentNullException(nameof(serialization)); - } this.compilationStatus.DllGeneration = 0; var fallbackFileName = (this.PathToCompiledBinary ?? this.config.ProjectNameWithExtension) ?? Path.GetRandomFileName(); @@ -1147,7 +1109,6 @@ public static bool ReadBinary(string file, [NotNullWhen(true)] out QsCompilation /// /// Given a stream with the content of a Q# binary file, returns the corresponding compilation as out parameter. - /// Throws an ArgumentNullException if the given stream is null. /// public static bool ReadBinary(Stream stream, [NotNullWhen(true)] out QsCompilation? syntaxTree) => AssemblyLoader.LoadSyntaxTree(stream, out syntaxTree); diff --git a/src/QsCompiler/Compiler/ExternalRewriteSteps.cs b/src/QsCompiler/Compiler/ExternalRewriteSteps.cs index 7dcfff6941..1ca8a87c49 100644 --- a/src/QsCompiler/Compiler/ExternalRewriteSteps.cs +++ b/src/QsCompiler/Compiler/ExternalRewriteSteps.cs @@ -62,8 +62,8 @@ private T InvokeViaReflection(string name, params object?[] args) => /// internal LoadedStep(object implementation, Type interfaceType, Uri origin) { - this.Origin = origin ?? throw new ArgumentNullException(nameof(origin)); - this.selfAsObject = implementation ?? throw new ArgumentNullException(nameof(implementation)); + this.Origin = origin; + this.selfAsObject = implementation; // Initializing the _InterfaceMethods even if the implementation implements IRewriteStep // would result in certain properties being loaded via reflection instead of simply being accessed via _SelfAsStep. diff --git a/src/QsCompiler/Compiler/FunctorGeneration.cs b/src/QsCompiler/Compiler/FunctorGeneration.cs index a7ca06fc62..739a64e234 100644 --- a/src/QsCompiler/Compiler/FunctorGeneration.cs +++ b/src/QsCompiler/Compiler/FunctorGeneration.cs @@ -31,14 +31,9 @@ public static class CodeGeneration /// /// Given a sequence of specializations, returns the implementation of the given kind, or null if no such specialization exists. /// Throws an ArgumentException if more than one specialization of that kind exist. - /// Throws an ArgumentNullException if the sequence of specializations is null, or contains any entries that are null. /// private static QsSpecialization? GetSpecialization(this IEnumerable specs, QsSpecializationKind kind) { - if (specs == null || specs.Any(s => s == null)) - { - throw new ArgumentNullException(nameof(specs)); - } specs = specs.Where(spec => spec.Kind == kind); if (specs.Count() > 1) { @@ -90,7 +85,6 @@ private static (QsTuple>, QsScope)? Body /// Only valid functor generator directives are evaluated, anything else remains unmodified. /// The directives 'invert' and 'self' are considered to be valid functor generator directives. /// Assumes that operation calls may only ever occur within expression statements. - /// Throws an ArgumentNullException if the given callable or a relevant property is null. /// Throws an ArgumentException if more than one body or adjoint specialization exists. /// Throws an ArgumentException if the callable is not intrinsic or external and the implementation for the body is not provided. /// @@ -99,7 +93,7 @@ private static QsCallable BuildAdjoint(this QsCallable callable) var bodyDecl = BodyImplementation(callable); if (bodyDecl == null) { - return callable ?? throw new ArgumentNullException(nameof(callable)); + return callable; } var adj = callable.Specializations.GetSpecialization(QsSpecializationKind.QsAdjoint); @@ -124,7 +118,6 @@ private static QsCallable BuildAdjoint(this QsCallable callable) /// or set to the original specialization if the specialization was not requested to be auto-generated. /// Only valid functor generator directives are evaluated, anything else remains unmodified. /// The directive 'distributed' is the only directive considered to be valid. - /// Throws an ArgumentNullException if the given callable or a relevant property is null. /// Throws an ArgumentException if more than one body or controlled specialization exists. /// Throws an ArgumentException if the callable is not intrinsic or external and the implementation for the body is not provided. /// @@ -133,7 +126,7 @@ private static QsCallable BuildControlled(this QsCallable callable) var bodyDecl = BodyImplementation(callable); if (bodyDecl == null) { - return callable ?? throw new ArgumentNullException(nameof(callable)); + return callable; } var ctl = callable.Specializations.GetSpecialization(QsSpecializationKind.QsControlled); @@ -158,7 +151,6 @@ private static QsCallable BuildControlled(this QsCallable callable) /// The directives 'invert', 'self', and 'distributed' are considered to be valid functor generator directives. /// Assumes that if the controlled adjoint version is to be generated based on the controlled version, /// operation calls may only ever occur within expression statements. - /// Throws an ArgumentNullException if the given callable or a relevant property is null. /// Throws an ArgumentException if more than one body, adjoint or controlled specialization (depending on the generator directive) exists. /// Throws an ArgumentException if the callable is not intrinsic or external and the implementation for the body is not provided, /// or if the implementation for the adjoint or controlled specialization (depending on the generator directive) is not provided. @@ -168,7 +160,7 @@ private static QsCallable BuildControlledAdjoint(this QsCallable callable) var bodyDecl = BodyImplementation(callable); if (bodyDecl == null) { - return callable ?? throw new ArgumentNullException(nameof(callable)); + return callable; } var ctlAdj = callable.Specializations.GetSpecialization(QsSpecializationKind.QsControlledAdjoint); @@ -200,14 +192,9 @@ private static QsCallable BuildControlledAdjoint(this QsCallable callable) /// This is the case e.g. if more than one specialization of the same kind exists for a callable which causes an ArgumentException to be thrown. /// Any thrown exception is logged using the given onException action and are silently ignored if onException is not specified or null. /// Returns a boolean indicating if the evaluation of all directives was successful. - /// Throws an ArgumentNullException (that is not logged or ignored) if the given compilation is null. /// public static bool GenerateFunctorSpecializations(QsCompilation compilation, out QsCompilation built, Action? onException = null) { - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } var success = true; var namespaces = compilation.Namespaces.Where(ns => ns != null).Select(ns => { diff --git a/src/QsCompiler/Compiler/Logging.cs b/src/QsCompiler/Compiler/Logging.cs index 5b5cf77a40..c706db4d08 100644 --- a/src/QsCompiler/Compiler/Logging.cs +++ b/src/QsCompiler/Compiler/Logging.cs @@ -153,14 +153,9 @@ private void Output(Diagnostic? msg) /// prints the given diagnostic ff the logger verbosity is sufficiently high. /// Before printing, the line numbers are shifted by the offset specified upon initialization. /// Returns without doing anything if the given diagnostic is a warning that is to be ignored. - /// Throws an ArgumentNullException if the given diagnostic is null. /// public void Log(Diagnostic m) { - if (m == null) - { - throw new ArgumentNullException(nameof(m)); - } if (m.Severity == DiagnosticSeverity.Warning && CompilationBuilder.Diagnostics.TryGetCode(m.Code, out int code) && this.noWarn.Contains(code)) @@ -183,14 +178,9 @@ public void Log(Diagnostic m) /// /// Increases the exception counter and calls OnException with the given exception. - /// Throws an ArgumentNullException if the given exception is null. /// public void Log(Exception ex) { - if (ex == null) - { - throw new ArgumentNullException(nameof(ex)); - } ++this.NrExceptionsLogged; this.OnException(ex); } @@ -205,14 +195,9 @@ public static class Formatting /// Returns a string that contains all information about the given diagnostic in human readable format. /// The string contains one-based position information if the range information is not null, /// assuming the given position information is zero-based. - /// Throws an ArgumentNullException if the given message is null. /// public static string HumanReadableFormat(Diagnostic msg) { - if (msg == null) - { - throw new ArgumentNullException(nameof(msg)); - } var codeStr = msg.Code == null ? string.Empty : $" {msg.Code}"; var (startLine, startChar) = (msg.Range?.Start?.Line + 1 ?? 0, msg.Range?.Start?.Character + 1 ?? 0); @@ -231,14 +216,9 @@ public static string HumanReadableFormat(Diagnostic msg) /// in a format that is detected and processed as a diagnostic by VS and VS Code. /// The string contains one-based position information if the range information is not null, /// assuming the given position information is zero-based. - /// Throws an ArgumentNullException if the given message is null. /// public static string MsBuildFormat(Diagnostic msg) { - if (msg == null) - { - throw new ArgumentNullException(nameof(msg)); - } var codeStr = msg.Code == null ? string.Empty : $" {msg.Code}"; var (startLine, startChar) = (msg.Range?.Start?.Line + 1 ?? 0, msg.Range?.Start?.Character + 1 ?? 0); diff --git a/src/QsCompiler/LanguageServer/EditorState.cs b/src/QsCompiler/LanguageServer/EditorState.cs index 35cbe022d4..479fd8e40e 100644 --- a/src/QsCompiler/LanguageServer/EditorState.cs +++ b/src/QsCompiler/LanguageServer/EditorState.cs @@ -84,7 +84,7 @@ internal EditorState( } }; - this.projectLoader = projectLoader ?? throw new ArgumentNullException(nameof(projectLoader)); + this.projectLoader = projectLoader; this.projects = new ProjectManager(onException, log, this.publish); this.openFiles = new ConcurrentDictionary(); this.onTemporaryProjectLoaded = onTemporaryProjectLoaded; @@ -161,7 +161,8 @@ internal bool QsProjectLoader(Uri projectFile, [NotNullWhen(true)] out ProjectIn internal Uri QsTemporaryProjectLoader(Uri sourceFileUri, string? sdkVersion) { var sourceFolderPath = Path.GetDirectoryName(sourceFileUri.LocalPath) ?? ""; - var projectFileName = string.Join("_x2f_", // arbitrary string to help avoid collisions + var projectFileName = string.Join( + "_x2f_", // arbitrary string to help avoid collisions sourceFolderPath .Replace("_", "_x5f_") // arbitrary string to help avoid collisions .Split(Path.GetInvalidFileNameChars())); @@ -184,7 +185,6 @@ internal Uri QsTemporaryProjectLoader(Uri sourceFileUri, string? sdkVersion) /// /// For each given uri, loads the corresponding project if the uri contains the project file for a Q# project, /// and publishes suitable diagnostics for it. - /// Throws an ArgumentNullException if the given sequence of uris, or if any of the contained uris is null. /// public Task LoadProjectsAsync(IEnumerable projects) => this.projects.LoadProjectsAsync(projects, this.QsProjectLoader, this.GetOpenFile); @@ -192,7 +192,6 @@ public Task LoadProjectsAsync(IEnumerable projects) => /// /// If the given uri corresponds to the project file for a Q# project, /// updates that project in the list of tracked projects or adds it if needed, and publishes suitable diagnostics for it. - /// Throws an ArgumentNullException if the given uri is null. /// public Task ProjectDidChangeOnDiskAsync(Uri project) => this.projects.ProjectChangedOnDiskAsync(project, this.QsProjectLoader, this.GetOpenFile); @@ -200,7 +199,6 @@ public Task ProjectDidChangeOnDiskAsync(Uri project) => /// /// Updates all tracked Q# projects that reference the assembly with the given uri /// either directly or indirectly via a reference to another Q# project, and publishes suitable diagnostics. - /// Throws an ArgumentNullException if the given uri is null. /// public Task AssemblyDidChangeOnDiskAsync(Uri dllPath) => this.projects.AssemblyChangedOnDiskAsync(dllPath); @@ -211,7 +209,6 @@ public Task AssemblyDidChangeOnDiskAsync(Uri dllPath) => /// if the file is not listed as currently being open in the editor, publishing suitable diagnostics. /// If the file is listed as being open in the editor, updates all load diagnostics for the file, /// but does not update the file content, since the editor manages that one. - /// Throws an ArgumentNullException if the given uri is null. /// public Task SourceFileDidChangeOnDiskAsync(Uri sourceFile) => this.projects.SourceFileChangedOnDiskAsync(sourceFile, this.GetOpenFile); @@ -225,22 +222,17 @@ public Task SourceFileDidChangeOnDiskAsync(Uri sourceFile) => /// Invokes the given Action showError with a suitable message if the given file cannot be loaded. /// Invokes the given Action logError with a suitable message if the given file cannot be associated with a compilation unit, /// or if the given file is already listed as being open in the editor. - /// Throws an ArgumentException if the uri of the given text document identifier is null or not an absolute file uri. - /// Throws an ArgumentNullException if the given content is null. + /// Throws an ArgumentException if the uri of the given text document identifier is not an absolute file uri. /// internal Task OpenFileAsync( TextDocumentItem textDocument, Action? showError = null, Action? logError = null) { - if (textDocument is null || !ValidFileUri(textDocument.Uri)) + if (!ValidFileUri(textDocument.Uri)) { throw new ArgumentException("invalid text document identifier"); } - if (textDocument.Text == null) - { - throw new ArgumentNullException(nameof(textDocument.Text)); - } // If the file is not associated with a project, we will create a temporary project file for all files in that folder. // We spawn a second query below for the actual processing of the file to ensure that a created project file // is properly registered with the project manager before processing. @@ -328,19 +320,14 @@ internal Task OpenFileAsync( /// /// To be called whenever a file is changed within the editor (i.e. changes are not necessarily reflected on disk). /// Does nothing if the given file is listed as to be ignored. - /// Throws an ArgumentException if the uri of the text document identifier in the given parameter is null or not an absolute file uri. - /// Throws an ArgumentNullException if the given content changes are null. + /// Throws an ArgumentException if the uri of the text document identifier in the given parameter is not an absolute file uri. /// internal Task DidChangeAsync(DidChangeTextDocumentParams param) { - if (param is null || param.TextDocument is null || !ValidFileUri(param.TextDocument.Uri)) + if (!ValidFileUri(param.TextDocument.Uri)) { throw new ArgumentException("invalid text document identifier"); } - if (param.ContentChanges == null) - { - throw new ArgumentNullException(nameof(param.ContentChanges)); - } return this.projects.ManagerTaskAsync(param.TextDocument.Uri, (manager, __) => { if (this.IgnoreFile(param.TextDocument.Uri)) @@ -362,19 +349,14 @@ internal Task DidChangeAsync(DidChangeTextDocumentParams param) /// Used to reload the file content when a file is saved. /// Does nothing if the given file is listed as to be ignored. /// Expects to get the entire content of the file at the time of saving as argument. - /// Throws an ArgumentException if the uri of the given text document identifier is null or not an absolute file uri. - /// Throws an ArgumentNullException if the given content is null. + /// Throws an ArgumentException if the uri of the given text document identifier is not an absolute file uri. /// internal Task SaveFileAsync(TextDocumentIdentifier textDocument, string fileContent) { - if (textDocument is null || !ValidFileUri(textDocument.Uri)) + if (!ValidFileUri(textDocument.Uri)) { throw new ArgumentException("invalid text document identifier"); } - if (fileContent == null) - { - throw new ArgumentNullException(nameof(fileContent)); - } return this.projects.ManagerTaskAsync(textDocument.Uri, (manager, __) => { if (this.IgnoreFile(textDocument.Uri)) diff --git a/src/QsCompiler/LanguageServer/FileSystemWatcher.cs b/src/QsCompiler/LanguageServer/FileSystemWatcher.cs index 22219deca5..0440f99f1f 100644 --- a/src/QsCompiler/LanguageServer/FileSystemWatcher.cs +++ b/src/QsCompiler/LanguageServer/FileSystemWatcher.cs @@ -56,9 +56,9 @@ private void OnBufferOverflow(object sender, ErrorEventArgs e) public delegate void FileEventHandler(FileEvent e); [PermissionSet(SecurityAction.Demand, Name = "FullTrust")] - public FileWatcher(Action? onException = null) + public FileWatcher(Action onException) { - this.onException = onException ?? throw new ArgumentNullException(nameof(onException)); + this.onException = onException; this.watchers = new ConcurrentBag(); this.watchedDirectories = new Dictionary>(); this.processing = new ProcessingQueue(this.onException, "error in file system watcher"); diff --git a/src/QsCompiler/LanguageServer/LanguageServer.cs b/src/QsCompiler/LanguageServer/LanguageServer.cs index 033d0cbe65..ddc17f9d25 100644 --- a/src/QsCompiler/LanguageServer/LanguageServer.cs +++ b/src/QsCompiler/LanguageServer/LanguageServer.cs @@ -189,7 +189,7 @@ public object Initialize(JToken arg) return new InitializeError { Retry = true }; } - arg?.SelectToken("capabilities.textDocument.codeAction")?.Replace(null); // setting this to null for now, since we are not using it and the deserialization causes issues + arg.SelectToken("capabilities.textDocument.codeAction")?.Replace(null); // setting this to null for now, since we are not using it and the deserialization causes issues var param = Utils.TryJTokenAs(arg); this.clientCapabilities = param.Capabilities; @@ -557,10 +557,10 @@ Command BuildCommand(string title, WorkspaceEdit edit) [JsonRpcMethod(Methods.WorkspaceExecuteCommandName)] public object? OnExecuteCommand(JToken arg) { - var param = Utils.TryJTokenAs(arg); + ExecuteCommandParams param = Utils.TryJTokenAs(arg); object? CastAndExecute(Func command) where T : class => QsCompilerError.RaiseOnFailure( - () => command(Utils.TryJTokenAs(param.Arguments.Single() as JObject)), // currently all supported commands take a single argument + () => command(Utils.TryJTokenAs((JObject)param.Arguments.Single())), // currently all supported commands take a single argument "ExecuteCommand threw an exception"); try { diff --git a/src/QsCompiler/LanguageServer/ProjectLoader.cs b/src/QsCompiler/LanguageServer/ProjectLoader.cs index 0e6513612a..f22bfc1cd9 100644 --- a/src/QsCompiler/LanguageServer/ProjectLoader.cs +++ b/src/QsCompiler/LanguageServer/ProjectLoader.cs @@ -173,20 +173,11 @@ internal string GetProjectNameHash(string projectFile) /// /// Loads the project corresponding to the given project file with the given properties, /// applies the given query to it, and unloads it. Returns the result of the query. - /// Throws an ArgumentNullException if the given query or properties are null. /// Throws an ArgumentException if the given project file is null or does not exist. /// NOTE: unloads the GlobalProjectCollection to force a cache clearing. /// private static T LoadAndApply(string projectFile, IDictionary properties, Func query) { - if (query == null) - { - throw new ArgumentNullException(nameof(query)); - } - if (properties == null) - { - throw new ArgumentNullException(nameof(properties)); - } if (!File.Exists(projectFile)) { throw new ArgumentException("given project file is null or does not exist", nameof(projectFile)); @@ -259,14 +250,9 @@ private static T LoadAndApply(string projectFile, IDictionary /// Returns a dictionary with additional project information (e.g. for telemetry) as out parameter. /// Logs suitable messages using the given log function if the project file cannot be found, or if the design time build fails. /// Logs whether or not the project is recognized as Q# project. - /// Throws an ArgumentNullException if the given project file is null. /// public ProjectInstance? TryGetQsProjectInstance(string projectFile, out Dictionary metadata) { - if (projectFile == null) - { - throw new ArgumentNullException(nameof(projectFile)); - } metadata = new Dictionary(); if (!projectFile.ToLowerInvariant().EndsWith(".csproj")) { diff --git a/src/QsCompiler/LanguageServer/SynchronizationContext.cs b/src/QsCompiler/LanguageServer/SynchronizationContext.cs index 5461d8376d..caaf7bd7c3 100644 --- a/src/QsCompiler/LanguageServer/SynchronizationContext.cs +++ b/src/QsCompiler/LanguageServer/SynchronizationContext.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; using System.Threading; using Microsoft.Quantum.QsCompiler; using Microsoft.VisualStudio.Threading; @@ -30,10 +29,6 @@ private void ProcessNext() /// public override void Post(SendOrPostCallback fct, object? arg) { - if (fct == null) - { - throw new ArgumentNullException(nameof(fct)); - } this.queued.Enqueue((fct, arg)); this.Send(_ => this.ProcessNext(), null); } diff --git a/src/QsCompiler/LanguageServer/Utils.cs b/src/QsCompiler/LanguageServer/Utils.cs index 5b4aa554f3..9bf8a6ea7b 100644 --- a/src/QsCompiler/LanguageServer/Utils.cs +++ b/src/QsCompiler/LanguageServer/Utils.cs @@ -17,49 +17,29 @@ public static class Utils // language server tools - // wrapping these into a try .. catch .. to make sure errors don't go unnoticed as they otherwise would - public static T TryJTokenAs(JToken? arg) where T : class => - QsCompilerError.RaiseOnFailure( - () => arg == null ? throw new ArgumentNullException(nameof(arg)) : arg.ToObject(), - "could not cast given JToken"); + public static T TryJTokenAs(JToken arg) where T : class => + QsCompilerError.RaiseOnFailure(() => arg.ToObject(), "could not cast given JToken"); private static ShowMessageParams? AsMessageParams(string text, MessageType severity) => text == null ? null : new ShowMessageParams { Message = text, MessageType = severity }; /// /// Shows the given text in the editor. - /// Throws an ArgumentNullException if either the server or the text to display is null. /// internal static void ShowInWindow(this QsLanguageServer server, string text, MessageType severity) { var message = AsMessageParams(text, severity); QsCompilerError.Verify(server != null && message != null, "cannot show message - given server or text was null"); - if (server == null) - { - throw new ArgumentNullException(nameof(server)); - } - if (message == null) - { - throw new ArgumentNullException(nameof(message)); - } _ = server.NotifyClientAsync(Methods.WindowShowMessageName, message); } /// /// Logs the given text in the editor. - /// Throws an ArgumentNullException if either the server or the text to display is null. /// internal static void LogToWindow(this QsLanguageServer server, string text, MessageType severity) { var message = AsMessageParams(text, severity); QsCompilerError.Verify(server != null && message != null, "cannot log message - given server or text was null"); - if (server == null) - { - throw new ArgumentNullException(nameof(server)); - } - if (message == null) - { - throw new ArgumentNullException(nameof(message)); - } _ = server.NotifyClientAsync(Methods.WindowLogMessageName, message); } @@ -76,15 +56,6 @@ internal static bool TryEnumerate( Func mapper, out ImmutableArray mapped) { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } - if (mapper == null) - { - throw new ArgumentNullException(nameof(mapper)); - } - var succeeded = true; var enumerator = source.GetEnumerator(); diff --git a/src/QsCompiler/Transformations/Attributes.cs b/src/QsCompiler/Transformations/Attributes.cs index 054e2358df..431fa9e8c0 100644 --- a/src/QsCompiler/Transformations/Attributes.cs +++ b/src/QsCompiler/Transformations/Attributes.cs @@ -51,7 +51,6 @@ public static TypedExpression StringArguments(params string[] items) => /// /// Adds the given attribute to all callables in the given compilation that satisfy the given predicate /// - if the predicate is specified and not null. - /// Throws an ArgumentNullException if the given attribute or compilation is null. /// public static QsCompilation AddToCallables(QsCompilation compilation, QsDeclarationAttribute attribute, CallablePredicate? predicate = null) => new AddAttributes(new[] { (attribute, predicate) }).OnCompilation(compilation); @@ -59,14 +58,12 @@ public static QsCompilation AddToCallables(QsCompilation compilation, QsDeclarat /// /// Adds the given attribute(s) to all callables in the given compilation that satisfy the given predicate /// - if the predicate is specified and not null. - /// Throws an ArgumentNullException if one of the given attributes or the compilation is null. /// public static QsCompilation AddToCallables(QsCompilation compilation, params (QsDeclarationAttribute, CallablePredicate?)[] attributes) => new AddAttributes(attributes).OnCompilation(compilation); /// /// Adds the given attribute(s) to all callables in the given compilation. - /// Throws an ArgumentNullException if one of the given attributes or the compilation is null. /// public static QsCompilation AddToCallables(QsCompilation compilation, params QsDeclarationAttribute[] attributes) => new AddAttributes(attributes.Select(att => (att, (CallablePredicate?)null))).OnCompilation(compilation); @@ -74,7 +71,6 @@ public static QsCompilation AddToCallables(QsCompilation compilation, params QsD /// /// Adds the given attribute to all callables in the given namespace that satisfy the given predicate /// - if the predicate is specified and not null. - /// Throws an ArgumentNullException if the given attribute or namespace is null. /// public static QsNamespace AddToCallables(QsNamespace ns, QsDeclarationAttribute attribute, CallablePredicate? predicate = null) => new AddAttributes(new[] { (attribute, predicate) }).Namespaces.OnNamespace(ns); @@ -82,14 +78,12 @@ public static QsNamespace AddToCallables(QsNamespace ns, QsDeclarationAttribute /// /// Adds the given attribute(s) to all callables in the given namespace that satisfy the given predicate /// - if the predicate is specified and not null. - /// Throws an ArgumentNullException if one of the given attributes or the namespace is null. /// public static QsNamespace AddToCallables(QsNamespace ns, params (QsDeclarationAttribute, CallablePredicate?)[] attributes) => new AddAttributes(attributes).Namespaces.OnNamespace(ns); /// /// Adds the given attribute(s) to all callables in the given namespace. - /// Throws an ArgumentNullException if one of the given attributes or the namespace is null. /// public static QsNamespace AddToCallables(QsNamespace ns, params QsDeclarationAttribute[] attributes) => new AddAttributes(attributes.Select(att => (att, (CallablePredicate?)null))).Namespaces.OnNamespace(ns); @@ -106,18 +100,13 @@ internal class TransformationState { internal readonly ImmutableArray<(QsDeclarationAttribute, CallablePredicate)> AttributeSelection; - /// Thrown when the given selection is null. - internal TransformationState(IEnumerable<(QsDeclarationAttribute, CallablePredicate)>? selections) => - this.AttributeSelection = selections?.ToImmutableArray() ?? throw new ArgumentNullException(nameof(selections)); + internal TransformationState(IEnumerable<(QsDeclarationAttribute, CallablePredicate)> selections) => + this.AttributeSelection = selections.ToImmutableArray(); } internal AddAttributes(IEnumerable<(QsDeclarationAttribute, CallablePredicate?)> attributes) - : base(new TransformationState(attributes?.Select(entry => (entry.Item1, entry.Item2 ?? (_ => true))))) + : base(new TransformationState(attributes.Select(entry => (entry.Item1, entry.Item2 ?? (_ => true))))) { - if (attributes == null || attributes.Any(entry => entry.Item1 == null)) - { - throw new ArgumentNullException(nameof(attributes)); - } this.Namespaces = new NamespaceTransformation(this); this.Statements = new Core.StatementTransformation(this, Core.TransformationOptions.Disabled); this.StatementKinds = new Core.StatementKindTransformation(this, Core.TransformationOptions.Disabled); diff --git a/src/QsCompiler/Transformations/BasicTransformations.cs b/src/QsCompiler/Transformations/BasicTransformations.cs index ef33337a1f..6aa3ef19af 100644 --- a/src/QsCompiler/Transformations/BasicTransformations.cs +++ b/src/QsCompiler/Transformations/BasicTransformations.cs @@ -33,14 +33,9 @@ private GetSourceFiles() /// /// Returns a hash set containing all source files in the given namespaces. - /// Throws an ArgumentNullException if the given sequence or any of the given namespaces is null. /// public static ImmutableHashSet> Apply(IEnumerable namespaces) { - if (namespaces == null || namespaces.Contains(null!)) - { - throw new ArgumentNullException(nameof(namespaces)); - } var filter = new GetSourceFiles(); foreach (var ns in namespaces) { @@ -51,7 +46,6 @@ public static ImmutableHashSet> Apply(IEnumerable /// Returns a hash set containing all source files in the given namespace(s). - /// Throws an ArgumentNullException if any of the given namespaces is null. /// public static ImmutableHashSet> Apply(params QsNamespace[] namespaces) => Apply((IEnumerable)namespaces); @@ -96,7 +90,7 @@ public class TransformationState new List<(int?, QsNamespaceElement)>(); public TransformationState(Func, bool> predicate) => - this.Predicate = predicate ?? throw new ArgumentNullException(nameof(predicate)); + this.Predicate = predicate; } public FilterBySourceFile(Func, bool> predicate) @@ -112,10 +106,6 @@ public FilterBySourceFile(Func, bool> predicate) public static QsNamespace Apply(QsNamespace ns, Func, bool> predicate) { - if (ns == null) - { - throw new ArgumentNullException(nameof(ns)); - } var filter = new FilterBySourceFile(predicate); return filter.Namespaces.OnNamespace(ns); } @@ -215,8 +205,8 @@ public TransformationState(Func condition, Func /// public StatementTransformation(Func createSelector, SyntaxTreeTransformation parent) : base(parent) => - this.CreateSelector = createSelector ?? throw new ArgumentNullException(nameof(createSelector)); + this.CreateSelector = createSelector; /// public override QsStatement OnStatement(QsStatement stm) @@ -357,11 +347,11 @@ public class TypedExpressionWalker { public TypedExpressionWalker(Action onExpression, SyntaxTreeTransformation parent) : base(parent, TransformationOptions.NoRebuild) => - this.OnExpression = onExpression ?? throw new ArgumentNullException(nameof(onExpression)); + this.OnExpression = onExpression; public TypedExpressionWalker(Action onExpression, T internalState = default) : base(internalState, TransformationOptions.NoRebuild) => - this.OnExpression = onExpression ?? throw new ArgumentNullException(nameof(onExpression)); + this.OnExpression = onExpression; public readonly Action OnExpression; diff --git a/src/QsCompiler/Transformations/CodeTransformations.cs b/src/QsCompiler/Transformations/CodeTransformations.cs index 8372c1d780..9b80bb041c 100644 --- a/src/QsCompiler/Transformations/CodeTransformations.cs +++ b/src/QsCompiler/Transformations/CodeTransformations.cs @@ -21,7 +21,6 @@ public static class CodeTransformations /// Given the body of an operation, auto-generates the (content of the) adjoint specialization, /// under the assumption that operation calls may only ever occur within expression statements, /// and while-loops cannot occur within operations. - /// Throws an ArgumentNullException if the given scope is null. /// public static QsScope GenerateAdjoint(this QsScope scope) { @@ -36,7 +35,6 @@ public static QsScope GenerateAdjoint(this QsScope scope) /// /// Given the body of an operation, auto-generates the (content of the) controlled specialization using the default name /// for control qubits. Adds the control qubits names to the list of defined variables for the scope and each subscope. - /// Throws an ArgumentNullException if the given scope is null. /// public static QsScope GenerateControlled(this QsScope scope) { @@ -51,14 +49,9 @@ public static QsScope GenerateControlled(this QsScope scope) /// throws an InvalidOperationException if the outer block contains while-loops. /// Any thrown exception is logged using the given onException action and silently ignored if onException is not specified or null. /// Returns true if the transformation succeeded without throwing an exception, and false otherwise. - /// Throws an ArgumentNullException (that is not logged or ignored) if the given compilation is null. /// public static bool InlineConjugations(this QsCompilation compilation, out QsCompilation inlined, Action? onException = null) { - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } var inline = new InlineConjugations(onException); var namespaces = compilation.Namespaces.Select(inline.Namespaces.OnNamespace).ToImmutableArray(); inlined = new QsCompilation(namespaces, compilation.EntryPoints); @@ -69,14 +62,9 @@ public static bool InlineConjugations(this QsCompilation compilation, out QsComp /// Pre-evaluates as much of the classical computations as possible in the given compilation. /// Any thrown exception is logged using the given onException action and silently ignored if onException is not specified or null. /// Returns true if the transformation succeeded without throwing an exception, and false otherwise. - /// Throws an ArgumentNullException (that is not logged or ignored) if the given compilation is null. /// public static bool PreEvaluateAll(this QsCompilation compilation, out QsCompilation evaluated, Action? onException = null) { - if (compilation == null) - { - throw new ArgumentNullException(nameof(compilation)); - } try { evaluated = PreEvaluation.All(compilation); diff --git a/src/QsCompiler/Transformations/FunctorGeneration.cs b/src/QsCompiler/Transformations/FunctorGeneration.cs index 83f3c40bf6..0e7b65fb25 100644 --- a/src/QsCompiler/Transformations/FunctorGeneration.cs +++ b/src/QsCompiler/Transformations/FunctorGeneration.cs @@ -28,8 +28,7 @@ public class TransformationsState { public readonly QsFunctor FunctorToApply; - public TransformationsState(QsFunctor functor) => - this.FunctorToApply = functor ?? throw new ArgumentNullException(nameof(functor)); + public TransformationsState(QsFunctor functor) => this.FunctorToApply = functor; } public ApplyFunctorToOperationCalls(QsFunctor functor) @@ -116,7 +115,7 @@ public class AddVariableDeclarations public AddVariableDeclarations(SyntaxTreeTransformation parent, params LocalVariableDeclaration>[] addedVars) : base(parent) => - this.addedVariableDeclarations = addedVars ?? throw new ArgumentNullException(nameof(addedVars)); + this.addedVariableDeclarations = addedVars; /// public override LocalDeclarations OnLocalDeclarations(LocalDeclarations decl) => diff --git a/src/QsCompiler/Transformations/Monomorphization.cs b/src/QsCompiler/Transformations/Monomorphization.cs index 13e2693806..b19bb61a45 100644 --- a/src/QsCompiler/Transformations/Monomorphization.cs +++ b/src/QsCompiler/Transformations/Monomorphization.cs @@ -46,11 +46,6 @@ private struct Response public static QsCompilation Apply(QsCompilation compilation) { - if (compilation == null || compilation.Namespaces.Contains(null)) - { - throw new ArgumentNullException(nameof(compilation)); - } - var globals = compilation.Namespaces.GlobalCallableResolutions(); var intrinsicCallableSet = globals diff --git a/src/QsCompiler/Transformations/QsharpCodeOutput.cs b/src/QsCompiler/Transformations/QsharpCodeOutput.cs index 627e085bfb..3405b41b0a 100644 --- a/src/QsCompiler/Transformations/QsharpCodeOutput.cs +++ b/src/QsCompiler/Transformations/QsharpCodeOutput.cs @@ -169,7 +169,6 @@ public static string DeclarationSignature(QsCallable c, Func IMPORTANT: The given namespace is expected to contain *all* elements in that namespace for the *entire* compilation unit! /// public static bool Apply( @@ -177,11 +176,6 @@ public static bool Apply( IEnumerable namespaces, params (NonNullable, ImmutableDictionary, ImmutableArray<(NonNullable, string?)>>)[] openDirectives) { - if (namespaces == null) - { - throw new ArgumentNullException(nameof(namespaces)); - } - generatedCode = new List, string>>(); var symbolsInNS = namespaces.ToImmutableDictionary(ns => ns.Name, ns => ns.Elements .SelectNotNull(element => (element as QsNamespaceElement.QsCallable)?.Item.FullName.Name.Value) diff --git a/src/QsCompiler/Transformations/SearchAndReplace.cs b/src/QsCompiler/Transformations/SearchAndReplace.cs index 3b66c96e69..853f0259e8 100644 --- a/src/QsCompiler/Transformations/SearchAndReplace.cs +++ b/src/QsCompiler/Transformations/SearchAndReplace.cs @@ -50,9 +50,9 @@ public class Location : IEquatable public Location(NonNullable source, Position declOffset, QsLocation stmLoc, Range range) { this.SourceFile = source; - this.DeclarationOffset = declOffset ?? throw new ArgumentNullException(nameof(declOffset)); - this.RelativeStatementLocation = stmLoc ?? throw new ArgumentNullException(nameof(stmLoc)); - this.SymbolRange = range ?? throw new ArgumentNullException(nameof(range)); + this.DeclarationOffset = declOffset; + this.RelativeStatementLocation = stmLoc; + this.SymbolRange = range; } /// @@ -117,7 +117,7 @@ internal TransformationState( QsLocation? defaultOffset = null, IImmutableSet>? limitToSourceFiles = null) { - this.TrackIdentifier = trackId ?? throw new ArgumentNullException(nameof(trackId)); + this.TrackIdentifier = trackId; this.relevantSourceFiles = limitToSourceFiles; this.Locations = ImmutableHashSet.Empty; this.defaultOffset = defaultOffset; @@ -133,7 +133,7 @@ public Position? DeclarationOffset internal get => this.rootOffset; set { - this.rootOffset = value ?? throw new ArgumentNullException(nameof(value), "declaration offset cannot be null"); + this.rootOffset = value; this.CurrentLocation = this.defaultOffset; } } @@ -187,10 +187,6 @@ public IdentifierReferences(NonNullable idName, QsLocation? defaultOffse public IdentifierReferences(QsQualifiedName idName, QsLocation? defaultOffset, IImmutableSet>? limitToSourceFiles = null) : this(new TransformationState(id => id is Identifier.GlobalCallable cName && cName.Item.Equals(idName), defaultOffset, limitToSourceFiles)) { - if (idName == null) - { - throw new ArgumentNullException(nameof(idName)); - } } // static methods for convenience @@ -199,12 +195,12 @@ public static ImmutableHashSet Find( NonNullable idName, QsScope scope, NonNullable sourceFile, - Position? rootLoc) + Position rootLoc) { var finder = new IdentifierReferences(idName, null, ImmutableHashSet.Create(sourceFile)); finder.SharedState.Source = sourceFile; - finder.SharedState.DeclarationOffset = rootLoc; // will throw if null - finder.Statements.OnScope(scope ?? throw new ArgumentNullException(nameof(scope))); + finder.SharedState.DeclarationOffset = rootLoc; + finder.Statements.OnScope(scope); return finder.SharedState.Locations; } @@ -216,7 +212,7 @@ public static ImmutableHashSet Find( IImmutableSet>? limitToSourceFiles = null) { var finder = new IdentifierReferences(idName, defaultOffset, limitToSourceFiles); - finder.Namespaces.OnNamespace(ns ?? throw new ArgumentNullException(nameof(ns))); + finder.Namespaces.OnNamespace(ns); declarationLocation = finder.SharedState.DeclarationLocation; return finder.SharedState.Locations; }