diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Async.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Async.cs index 156c28696..7e918263d 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Async.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Async.cs @@ -193,7 +193,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty catch (Exception ex) { await Task.Delay(0); +#pragma warning disable CA2200 // Rethrow to preserve stack details throw ex; +#pragma warning restore CA2200 // Rethrow to preserve stack details } } diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExceptionHandling.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExceptionHandling.cs index a8165c833..82aba9ab6 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExceptionHandling.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExceptionHandling.cs @@ -480,7 +480,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty catch (Exception ex) when (ex.Data.IsFixedSize) { Console.WriteLine(ex.ToString()); +#pragma warning disable CA2200 // Rethrow to preserve stack details throw ex; +#pragma warning restore CA2200 // Rethrow to preserve stack details } } @@ -493,7 +495,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty catch (Exception ex) when (ex is InternalBufferOverflowException) { Console.WriteLine(ex.ToString()); +#pragma warning disable CA2200 // Rethrow to preserve stack details throw ex; +#pragma warning restore CA2200 // Rethrow to preserve stack details } } #endif diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/PInvoke.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/PInvoke.cs index 7ec581a14..b8483ecc1 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/PInvoke.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/PInvoke.cs @@ -53,6 +53,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty public int bottom; } +#pragma warning disable CS0618 // Type or member is obsolete public static decimal MarshalAttributesOnPropertyAccessors { [return: MarshalAs(UnmanagedType.Currency)] get { @@ -62,6 +63,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty set { } } +#pragma warning restore CS0618 // Type or member is obsolete [DllImport("xyz.dll", CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.Bool)] diff --git a/ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs b/ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs index 78e3fe3f8..9de8f2998 100644 --- a/ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs +++ b/ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs @@ -217,7 +217,9 @@ namespace ICSharpCode.Decompiler.Metadata public PEFile? ResolveModule(PEFile mainModule, string moduleName) { - string baseDirectory = Path.GetDirectoryName(mainModule.FileName); + string? baseDirectory = Path.GetDirectoryName(mainModule.FileName); + if (baseDirectory == null) + return null; string moduleFileName = Path.Combine(baseDirectory, moduleName); return CreatePEFileFromFileName(moduleFileName, ex => new ResolutionException(mainModule.FileName, moduleName, moduleFileName, ex)); } @@ -381,7 +383,7 @@ namespace ICSharpCode.Decompiler.Metadata return null; } - string FindClosestVersionDirectory(string? basePath, Version? version) + string FindClosestVersionDirectory(string basePath, Version? version) { string? path = null; foreach (var folder in new DirectoryInfo(basePath).GetDirectories().Select(d => DotNetCorePathFinder.ConvertToVersion(d.Name)) @@ -402,7 +404,7 @@ namespace ICSharpCode.Decompiler.Metadata if (assembly != null) return assembly; - var framework_dir = Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName); + var framework_dir = Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName)!; var framework_dirs = decompilerRuntime == DecompilerRuntime.Mono ? new[] { framework_dir, Path.Combine(framework_dir, "Facades") } : new[] { framework_dir }; @@ -444,6 +446,8 @@ namespace ICSharpCode.Decompiler.Metadata { foreach (var directory in directories) { + if (directory == null) + continue; string? file = SearchDirectory(name, directory); if (file != null) return file; @@ -457,7 +461,7 @@ namespace ICSharpCode.Decompiler.Metadata return IsZeroOrAllOnes(reference.Version) || reference.IsRetargetable; } - string? SearchDirectory(IAssemblyReference name, string? directory) + string? SearchDirectory(IAssemblyReference name, string directory) { var extensions = name.IsWindowsRuntime ? new[] { ".winmd", ".dll" } : new[] { ".dll", ".exe" }; foreach (var extension in extensions) @@ -581,7 +585,7 @@ namespace ICSharpCode.Decompiler.Metadata string? GetMonoMscorlibBasePath(Version version) { - var path = Directory.GetParent(typeof(object).Module.FullyQualifiedName).Parent.FullName; + var path = Directory.GetParent(typeof(object).Module.FullyQualifiedName)!.Parent!.FullName; if (version.Major == 1) path = Path.Combine(path, "1.0"); else if (version.Major == 2) @@ -646,7 +650,7 @@ namespace ICSharpCode.Decompiler.Metadata { return Path.Combine( Directory.GetParent( - Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName)).FullName, + Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName)!)!.FullName, "gac"); } @@ -693,7 +697,7 @@ namespace ICSharpCode.Decompiler.Metadata return null; } - static string GetAssemblyFile(IAssemblyReference reference, string? prefix, string? gac) + static string GetAssemblyFile(IAssemblyReference reference, string prefix, string gac) { var gac_folder = new StringBuilder() .Append(prefix) @@ -719,8 +723,8 @@ namespace ICSharpCode.Decompiler.Metadata continue; foreach (var item in new DirectoryInfo(rootPath).EnumerateFiles("*.dll", SearchOption.AllDirectories)) { - string[] name = Path.GetDirectoryName(item.FullName).Substring(rootPath.Length + 1).Split(new[] { "\\" }, StringSplitOptions.RemoveEmptyEntries); - if (name.Length != 2) + string[]? name = Path.GetDirectoryName(item.FullName)?.Substring(rootPath.Length + 1).Split(new[] { "\\" }, StringSplitOptions.RemoveEmptyEntries); + if (name?.Length != 2) continue; var match = Regex.Match(name[1], $"(v4.0_)?(?[^_]+)_(?[^_]+)?_(?[^_]+)"); if (!match.Success) diff --git a/ICSharpCode.Decompiler/Util/CollectionExtensions.cs b/ICSharpCode.Decompiler/Util/CollectionExtensions.cs index 6bc2132fd..e847c0bca 100644 --- a/ICSharpCode.Decompiler/Util/CollectionExtensions.cs +++ b/ICSharpCode.Decompiler/Util/CollectionExtensions.cs @@ -15,7 +15,7 @@ namespace ICSharpCode.Decompiler.Util } #if !NETCORE - public static IEnumerable<(A, B)> Zip(this IEnumerable? input1, IEnumerable? input2) + public static IEnumerable<(A, B)> Zip(this IEnumerable input1, IEnumerable input2) { return input1.Zip(input2, (a, b) => (a, b)); } @@ -61,7 +61,7 @@ namespace ICSharpCode.Decompiler.Util } #if !NETCORE - public static HashSet ToHashSet(this IEnumerable? input) + public static HashSet ToHashSet(this IEnumerable input) { return new HashSet(input); } @@ -354,7 +354,7 @@ namespace ICSharpCode.Decompiler.Util list.RemoveAt(list.Count - 1); } - public static T? OnlyOrDefault(this IEnumerable? source, Func? predicate) => OnlyOrDefault(source.Where(predicate)); + public static T? OnlyOrDefault(this IEnumerable source, Func predicate) => OnlyOrDefault(source.Where(predicate)); public static T? OnlyOrDefault(this IEnumerable source) { @@ -373,14 +373,14 @@ namespace ICSharpCode.Decompiler.Util #region Aliases/shortcuts for Enumerable extension methods public static bool Any(this ICollection list) => list.Count > 0; - public static bool Any(this T[]? array, Predicate? match) => Array.Exists(array, match); - public static bool Any(this List list, Predicate? match) => list.Exists(match); + public static bool Any(this T[] array, Predicate match) => Array.Exists(array, match); + public static bool Any(this List list, Predicate match) => list.Exists(match); - public static bool All(this T[]? array, Predicate? match) => Array.TrueForAll(array, match); - public static bool All(this List list, Predicate? match) => list.TrueForAll(match); + public static bool All(this T[] array, Predicate match) => Array.TrueForAll(array, match); + public static bool All(this List list, Predicate match) => list.TrueForAll(match); - public static T FirstOrDefault(this T[]? array, Predicate? predicate) => Array.Find(array, predicate); - public static T FirstOrDefault(this List list, Predicate? predicate) => list.Find(predicate); + public static T? FirstOrDefault(this T[] array, Predicate predicate) => Array.Find(array, predicate); + public static T? FirstOrDefault(this List list, Predicate predicate) => list.Find(predicate); public static T Last(this IList list) => list[list.Count - 1]; #endregion diff --git a/ICSharpCode.Decompiler/Util/KeyComparer.cs b/ICSharpCode.Decompiler/Util/KeyComparer.cs index b1412d09b..46e9b9d21 100644 --- a/ICSharpCode.Decompiler/Util/KeyComparer.cs +++ b/ICSharpCode.Decompiler/Util/KeyComparer.cs @@ -69,12 +69,12 @@ namespace ICSharpCode.Decompiler.Util this.keyEqualityComparer = keyEqualityComparer; } - public int Compare(TElement x, TElement y) + public int Compare(TElement? x, TElement? y) { return keyComparer.Compare(keySelector(x), keySelector(y)); } - public bool Equals(TElement x, TElement y) + public bool Equals(TElement? x, TElement? y) { return keyEqualityComparer.Equals(keySelector(x), keySelector(y)); } diff --git a/ICSharpCode.Decompiler/Util/LongSet.cs b/ICSharpCode.Decompiler/Util/LongSet.cs index ac23cc67c..9fc58ed92 100644 --- a/ICSharpCode.Decompiler/Util/LongSet.cs +++ b/ICSharpCode.Decompiler/Util/LongSet.cs @@ -83,7 +83,7 @@ namespace ICSharpCode.Decompiler.Util /// /// Creates a new LongSet the contains the values from the specified intervals. /// - public LongSet(IEnumerable? intervals) + public LongSet(IEnumerable intervals) : this(MergeOverlapping(intervals.Where(i => !i.IsEmpty).OrderBy(i => i.Start)).ToImmutableArray()) { } diff --git a/ICSharpCode.Decompiler/Util/MultiDictionary.cs b/ICSharpCode.Decompiler/Util/MultiDictionary.cs index 3bdfd989b..52a451f5a 100644 --- a/ICSharpCode.Decompiler/Util/MultiDictionary.cs +++ b/ICSharpCode.Decompiler/Util/MultiDictionary.cs @@ -25,7 +25,7 @@ namespace ICSharpCode.Decompiler.Util /// /// A dictionary that allows multiple pairs with the same key. /// - public class MultiDictionary : ILookup + public class MultiDictionary : ILookup where TKey : notnull { readonly Dictionary> dict; @@ -41,8 +41,7 @@ namespace ICSharpCode.Decompiler.Util public void Add(TKey key, TValue value) { - List valueList; - if (!dict.TryGetValue(key, out valueList)) + if (!dict.TryGetValue(key, out List? valueList)) { valueList = new List(); dict.Add(key, valueList); @@ -52,8 +51,7 @@ namespace ICSharpCode.Decompiler.Util public bool Remove(TKey key, TValue value) { - List valueList; - if (dict.TryGetValue(key, out valueList)) + if (dict.TryGetValue(key, out List? valueList)) { if (valueList.Remove(value)) { diff --git a/ICSharpCode.Decompiler/Util/UnionFind.cs b/ICSharpCode.Decompiler/Util/UnionFind.cs index 15c06f2d7..087cd1b8f 100644 --- a/ICSharpCode.Decompiler/Util/UnionFind.cs +++ b/ICSharpCode.Decompiler/Util/UnionFind.cs @@ -24,7 +24,7 @@ namespace ICSharpCode.Decompiler.Util /// /// Union-Find data structure. /// - public class UnionFind + public class UnionFind where T : notnull { Dictionary mapping; @@ -48,8 +48,7 @@ namespace ICSharpCode.Decompiler.Util Node GetNode(T element) { - Node node; - if (!mapping.TryGetValue(element, out node)) + if (!mapping.TryGetValue(element, out Node? node)) { node = new Node(element); node.parent = node; diff --git a/ILSpy/Analyzers/Builtin/FindTypeInAttributeDecoder.cs b/ILSpy/Analyzers/Builtin/FindTypeInAttributeDecoder.cs index 329736655..1431e3cee 100644 --- a/ILSpy/Analyzers/Builtin/FindTypeInAttributeDecoder.cs +++ b/ILSpy/Analyzers/Builtin/FindTypeInAttributeDecoder.cs @@ -65,7 +65,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin public FindTypeInAttributeDecoder(MetadataModule currentModule, ITypeDefinition type) { this.currentModule = currentModule; - this.declaringModule = type.ParentModule.PEFile ?? throw new InvalidOperationException("Cannot use MetadataModule without PEFile as context."); + this.declaringModule = type.ParentModule?.PEFile ?? throw new InvalidOperationException("Cannot use MetadataModule without PEFile as context."); this.handle = (TypeDefinitionHandle)type.MetadataToken; this.primitiveType = type.KnownTypeCode == KnownTypeCode.None ? 0 : type.KnownTypeCode.ToPrimitiveTypeCode(); } @@ -138,7 +138,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin { result = TokenSearchResult.SystemType; } - if (td.MetadataToken == this.handle && td.ParentModule.PEFile == declaringModule) + if (td.MetadataToken == this.handle && td.ParentModule?.PEFile == declaringModule) { result |= TokenSearchResult.Found; } diff --git a/ILSpy/Languages/CSharpLexer.cs b/ILSpy/Languages/CSharpLexer.cs index 56d4f5e10..9e5685ac8 100644 --- a/ILSpy/Languages/CSharpLexer.cs +++ b/ILSpy/Languages/CSharpLexer.cs @@ -107,7 +107,7 @@ namespace ICSharpCode.ILSpy } } - internal abstract class AbstractLexer + internal abstract class AbstractLexer : IDisposable { LATextReader reader; int col = 1;