From b9eee606af05f149efab0fe789ed3cbc573992d9 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Thu, 3 Jun 2021 20:32:18 +0200 Subject: [PATCH 1/6] #nullable enable for most files in ICSharpCode.Decompiler/Util --- ICSharpCode.Decompiler/Util/BitSet.cs | 1 + ICSharpCode.Decompiler/Util/BusyManager.cs | 13 +++---- .../Util/CSharpPrimitiveCast.cs | 6 +++- ICSharpCode.Decompiler/Util/CacheManager.cs | 2 ++ .../Util/CallbackOnDispose.cs | 6 ++-- .../Util/CollectionExtensions.cs | 35 ++++++++++--------- ICSharpCode.Decompiler/Util/EmptyList.cs | 5 +-- .../Util/ExtensionMethods.cs | 5 +-- ICSharpCode.Decompiler/Util/FileUtility.cs | 24 ++++++++----- ICSharpCode.Decompiler/Util/GraphVizGraph.cs | 26 +++++++------- ICSharpCode.Decompiler/Util/Interval.cs | 7 ++-- ICSharpCode.Decompiler/Util/KeyComparer.cs | 3 +- ICSharpCode.Decompiler/Util/LongSet.cs | 7 ++-- .../Util/MultiDictionary.cs | 5 +-- ICSharpCode.Decompiler/Util/Platform.cs | 3 +- ICSharpCode.Decompiler/Util/ProjectedList.cs | 15 ++++---- .../Util/ReferenceComparer.cs | 7 ++-- ICSharpCode.Decompiler/Util/ResourcesFile.cs | 27 +++++++------- ICSharpCode.Decompiler/Util/TreeTraversal.cs | 15 ++++---- ICSharpCode.Decompiler/Util/UnicodeNewline.cs | 7 ++-- ICSharpCode.Decompiler/Util/UnionFind.cs | 14 ++++---- ICSharpCode.Decompiler/Util/Win32Resources.cs | 23 ++++++------ .../ILSpy.BamlDecompiler.Tests.csproj | 4 +-- 23 files changed, 147 insertions(+), 113 deletions(-) diff --git a/ICSharpCode.Decompiler/Util/BitSet.cs b/ICSharpCode.Decompiler/Util/BitSet.cs index 9ca0a2b0c..5d7ecf429 100644 --- a/ICSharpCode.Decompiler/Util/BitSet.cs +++ b/ICSharpCode.Decompiler/Util/BitSet.cs @@ -15,6 +15,7 @@ // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#nullable enable using System; using System.Diagnostics; diff --git a/ICSharpCode.Decompiler/Util/BusyManager.cs b/ICSharpCode.Decompiler/Util/BusyManager.cs index f277fc40a..abe2aeba4 100644 --- a/ICSharpCode.Decompiler/Util/BusyManager.cs +++ b/ICSharpCode.Decompiler/Util/BusyManager.cs @@ -15,6 +15,7 @@ // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#nullable enable using System; using System.Collections.Generic; @@ -36,9 +37,9 @@ namespace ICSharpCode.Decompiler.Util { public static readonly BusyLock Failed = new BusyLock(null); - readonly List objectList; + readonly List? objectList; - internal BusyLock(List objectList) + internal BusyLock(List? objectList) { this.objectList = objectList; } @@ -56,13 +57,13 @@ namespace ICSharpCode.Decompiler.Util } } - [ThreadStatic] static List _activeObjects; + [ThreadStatic] static List? _activeObjects; - public static BusyLock Enter(object obj) + public static BusyLock Enter(object? obj) { - List activeObjects = _activeObjects; + List? activeObjects = _activeObjects; if (activeObjects == null) - activeObjects = _activeObjects = new List(); + activeObjects = _activeObjects = new List(); for (int i = 0; i < activeObjects.Count; i++) { if (activeObjects[i] == obj) diff --git a/ICSharpCode.Decompiler/Util/CSharpPrimitiveCast.cs b/ICSharpCode.Decompiler/Util/CSharpPrimitiveCast.cs index b57516b45..cfc8c854c 100644 --- a/ICSharpCode.Decompiler/Util/CSharpPrimitiveCast.cs +++ b/ICSharpCode.Decompiler/Util/CSharpPrimitiveCast.cs @@ -16,7 +16,10 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#nullable enable + using System; +using System.Diagnostics.CodeAnalysis; namespace ICSharpCode.Decompiler.Util { @@ -34,7 +37,8 @@ namespace ICSharpCode.Decompiler.Util /// /// Overflow checking is enabled and an overflow occurred. /// The cast is invalid, e.g. casting a boolean to an integer. - public static object Cast(TypeCode targetType, object input, bool checkForOverflow) + [return: NotNullIfNotNull("input")] + public static object? Cast(TypeCode targetType, object? input, bool checkForOverflow) { if (input == null) return null; diff --git a/ICSharpCode.Decompiler/Util/CacheManager.cs b/ICSharpCode.Decompiler/Util/CacheManager.cs index 75bef2203..2c3bae375 100644 --- a/ICSharpCode.Decompiler/Util/CacheManager.cs +++ b/ICSharpCode.Decompiler/Util/CacheManager.cs @@ -16,6 +16,8 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#nullable enable + using System; using System.Collections.Concurrent; diff --git a/ICSharpCode.Decompiler/Util/CallbackOnDispose.cs b/ICSharpCode.Decompiler/Util/CallbackOnDispose.cs index ac83ff562..cb02b5321 100644 --- a/ICSharpCode.Decompiler/Util/CallbackOnDispose.cs +++ b/ICSharpCode.Decompiler/Util/CallbackOnDispose.cs @@ -16,6 +16,8 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#nullable enable + using System; using System.Threading; @@ -30,7 +32,7 @@ namespace ICSharpCode.Decompiler.Util /// public sealed class CallbackOnDispose : IDisposable { - Action action; + Action? action; public CallbackOnDispose(Action action) { @@ -41,7 +43,7 @@ namespace ICSharpCode.Decompiler.Util public void Dispose() { - Action a = Interlocked.Exchange(ref action, null); + Action? a = Interlocked.Exchange(ref action, null); if (a != null) { a(); diff --git a/ICSharpCode.Decompiler/Util/CollectionExtensions.cs b/ICSharpCode.Decompiler/Util/CollectionExtensions.cs index 2b54131a9..6bc2132fd 100644 --- a/ICSharpCode.Decompiler/Util/CollectionExtensions.cs +++ b/ICSharpCode.Decompiler/Util/CollectionExtensions.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; @@ -14,13 +15,13 @@ 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)); } #endif - public static IEnumerable<(A, B)> ZipLongest(this IEnumerable input1, IEnumerable input2) + public static IEnumerable<(A?, B?)> ZipLongest(this IEnumerable input1, IEnumerable input2) { using (var it1 = input1.GetEnumerator()) { @@ -60,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); } @@ -76,14 +77,14 @@ namespace ICSharpCode.Decompiler.Util return input.Skip(input.Count - count); } - public static T PopOrDefault(this Stack stack) + public static T? PopOrDefault(this Stack stack) { if (stack.Count == 0) return default(T); return stack.Pop(); } - public static T PeekOrDefault(this Stack stack) + public static T? PeekOrDefault(this Stack stack) { if (stack.Count == 0) return default(T); @@ -277,7 +278,7 @@ namespace ICSharpCode.Decompiler.Util /// Returns the minimum element. /// /// The input sequence is empty - public static T MinBy(this IEnumerable source, Func keySelector, IComparer keyComparer) + public static T MinBy(this IEnumerable source, Func keySelector, IComparer? keyComparer) { if (source == null) throw new ArgumentNullException(nameof(source)); @@ -318,7 +319,7 @@ namespace ICSharpCode.Decompiler.Util /// Returns the maximum element. /// /// The input sequence is empty - public static T MaxBy(this IEnumerable source, Func keySelector, IComparer keyComparer) + public static T MaxBy(this IEnumerable source, Func keySelector, IComparer? keyComparer) { if (source == null) throw new ArgumentNullException(nameof(source)); @@ -353,12 +354,12 @@ 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) + public static T? OnlyOrDefault(this IEnumerable source) { bool any = false; - T first = default; + T? first = default; foreach (var t in source) { if (any) @@ -372,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/EmptyList.cs b/ICSharpCode.Decompiler/Util/EmptyList.cs index 2b4e6c45d..f02871910 100644 --- a/ICSharpCode.Decompiler/Util/EmptyList.cs +++ b/ICSharpCode.Decompiler/Util/EmptyList.cs @@ -15,6 +15,7 @@ // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#nullable enable using System; using System.Collections; @@ -91,11 +92,11 @@ namespace ICSharpCode.Decompiler.Util } T IEnumerator.Current { - get { return default(T); } + get { throw new NotSupportedException(); } } object IEnumerator.Current { - get { return default(T); } + get { throw new NotSupportedException(); } } void IDisposable.Dispose() diff --git a/ICSharpCode.Decompiler/Util/ExtensionMethods.cs b/ICSharpCode.Decompiler/Util/ExtensionMethods.cs index 57c97199a..bdb070712 100644 --- a/ICSharpCode.Decompiler/Util/ExtensionMethods.cs +++ b/ICSharpCode.Decompiler/Util/ExtensionMethods.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team +#nullable enable +// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -26,7 +27,7 @@ namespace ICSharpCode.Decompiler.Util /// static class ExtensionMethods { - public static Predicate And(this Predicate filter1, Predicate filter2) + public static Predicate? And(this Predicate? filter1, Predicate? filter2) { if (filter1 == null) return filter2; diff --git a/ICSharpCode.Decompiler/Util/FileUtility.cs b/ICSharpCode.Decompiler/Util/FileUtility.cs index aaf26fa06..d2d93923f 100644 --- a/ICSharpCode.Decompiler/Util/FileUtility.cs +++ b/ICSharpCode.Decompiler/Util/FileUtility.cs @@ -16,7 +16,10 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#nullable enable + using System; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; @@ -28,9 +31,10 @@ namespace ICSharpCode.Decompiler.Util /// Gets the normalized version of fileName. /// Slashes are replaced with backslashes, backreferences "." and ".." are 'evaluated'. /// - public static string NormalizePath(string fileName) + [return: NotNullIfNotNull("fileName")] + public static string? NormalizePath(string? fileName) { - if (string.IsNullOrEmpty(fileName)) + if (fileName == null || fileName.Length == 0) return fileName; int i; @@ -169,14 +173,14 @@ namespace ICSharpCode.Decompiler.Util && (fileName[1] == '\\' || fileName[1] == '/'); } - public static bool IsEqualFileName(string fileName1, string fileName2) + public static bool IsEqualFileName(string? fileName1, string? fileName2) { return string.Equals(NormalizePath(fileName1), NormalizePath(fileName2), StringComparison.OrdinalIgnoreCase); } - public static bool IsBaseDirectory(string baseDirectory, string testDirectory) + public static bool IsBaseDirectory(string? baseDirectory, string? testDirectory) { if (baseDirectory == null || testDirectory == null) return false; @@ -189,9 +193,10 @@ namespace ICSharpCode.Decompiler.Util return testDirectory.StartsWith(baseDirectory, StringComparison.OrdinalIgnoreCase); } - static string AddTrailingSeparator(string input) + [return: NotNullIfNotNull("input")] + static string? AddTrailingSeparator(string? input) { - if (string.IsNullOrEmpty(input)) + if (input == null || input.Length == 0) return input; if (input[input.Length - 1] == Path.DirectorySeparatorChar || input[input.Length - 1] == Path.AltDirectorySeparatorChar) return input; @@ -212,9 +217,9 @@ namespace ICSharpCode.Decompiler.Util /// Converts a given absolute path and a given base path to a path that leads /// from the base path to the absoulte path. (as a relative path) /// - public static string GetRelativePath(string baseDirectoryPath, string absPath) + public static string GetRelativePath(string? baseDirectoryPath, string absPath) { - if (string.IsNullOrEmpty(baseDirectoryPath)) + if (baseDirectoryPath == null || baseDirectoryPath.Length == 0) { return absPath; } @@ -252,7 +257,8 @@ namespace ICSharpCode.Decompiler.Util return erg.ToString(); } - public static string TrimPath(string path, int max_chars) + [return: NotNullIfNotNull("path")] + public static string? TrimPath(string? path, int max_chars) { const char ellipsis = '\u2026'; // HORIZONTAL ELLIPSIS const int ellipsisLength = 2; diff --git a/ICSharpCode.Decompiler/Util/GraphVizGraph.cs b/ICSharpCode.Decompiler/Util/GraphVizGraph.cs index bfa574005..92069e7d9 100644 --- a/ICSharpCode.Decompiler/Util/GraphVizGraph.cs +++ b/ICSharpCode.Decompiler/Util/GraphVizGraph.cs @@ -16,6 +16,8 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#nullable enable + using System; using System.Collections.Generic; using System.Diagnostics; @@ -34,8 +36,8 @@ namespace ICSharpCode.Decompiler.Util List nodes = new List(); List edges = new List(); - public string rankdir; - public string Title; + public string? rankdir; + public string? Title; public void AddEdge(GraphVizEdge edge) { @@ -58,7 +60,7 @@ namespace ICSharpCode.Decompiler.Util Show(null); } - public void Show(string name) + public void Show(string? name) { if (name == null) name = Title; @@ -83,7 +85,7 @@ namespace ICSharpCode.Decompiler.Util } } - static void WriteGraphAttribute(TextWriter writer, string name, string value) + static void WriteGraphAttribute(TextWriter writer, string name, string? value) { if (value != null) writer.WriteLine("{0}={1};", name, Escape(value)); @@ -105,7 +107,7 @@ namespace ICSharpCode.Decompiler.Util } } - internal static void WriteAttribute(TextWriter writer, string name, string value, ref bool isFirst) + internal static void WriteAttribute(TextWriter writer, string name, string? value, ref bool isFirst) { if (value != null) { @@ -141,13 +143,13 @@ namespace ICSharpCode.Decompiler.Util public readonly string Source, Target; /// edge stroke color - public string color; + public string? color; /// use edge to affect node ranking public bool? constraint; - public string label; + public string? label; - public string style; + public string? style; /// point size of label public int? fontsize; @@ -184,9 +186,9 @@ namespace ICSharpCode.Decompiler.Util sealed class GraphVizNode { public readonly string ID; - public string label; + public string? label; - public string labelloc; + public string? labelloc; /// point size of label public int? fontsize; @@ -195,10 +197,10 @@ namespace ICSharpCode.Decompiler.Util public double? height; /// space around label - public string margin; + public string? margin; /// node shape - public string shape; + public string? shape; public GraphVizNode(string id) { diff --git a/ICSharpCode.Decompiler/Util/Interval.cs b/ICSharpCode.Decompiler/Util/Interval.cs index 7dd74f64a..7a50e2b1e 100644 --- a/ICSharpCode.Decompiler/Util/Interval.cs +++ b/ICSharpCode.Decompiler/Util/Interval.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2016 Daniel Grunwald +#nullable enable +// Copyright (c) 2016 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -111,7 +112,7 @@ namespace ICSharpCode.Decompiler.Util } #region Equals and GetHashCode implementation - public override bool Equals(object obj) + public override bool Equals(object? obj) { return (obj is Interval) && Equals((Interval)obj); } @@ -281,7 +282,7 @@ namespace ICSharpCode.Decompiler.Util } #region Equals and GetHashCode implementation - public override bool Equals(object obj) + public override bool Equals(object? obj) { return (obj is LongInterval) && Equals((LongInterval)obj); } diff --git a/ICSharpCode.Decompiler/Util/KeyComparer.cs b/ICSharpCode.Decompiler/Util/KeyComparer.cs index 7cd6d7047..b1412d09b 100644 --- a/ICSharpCode.Decompiler/Util/KeyComparer.cs +++ b/ICSharpCode.Decompiler/Util/KeyComparer.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team +#nullable enable +// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software diff --git a/ICSharpCode.Decompiler/Util/LongSet.cs b/ICSharpCode.Decompiler/Util/LongSet.cs index 697c43330..ac23cc67c 100644 --- a/ICSharpCode.Decompiler/Util/LongSet.cs +++ b/ICSharpCode.Decompiler/Util/LongSet.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2016 Daniel Grunwald +#nullable enable +// Copyright (c) 2016 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -82,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()) { } @@ -350,7 +351,7 @@ namespace ICSharpCode.Decompiler.Util } #region Equals and GetHashCode implementation - public override bool Equals(object obj) + public override bool Equals(object? obj) { return obj is LongSet && SetEquals((LongSet)obj); } diff --git a/ICSharpCode.Decompiler/Util/MultiDictionary.cs b/ICSharpCode.Decompiler/Util/MultiDictionary.cs index ec93a866c..3bdfd989b 100644 --- a/ICSharpCode.Decompiler/Util/MultiDictionary.cs +++ b/ICSharpCode.Decompiler/Util/MultiDictionary.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team +#nullable enable +// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -33,7 +34,7 @@ namespace ICSharpCode.Decompiler.Util dict = new Dictionary>(); } - public MultiDictionary(IEqualityComparer comparer) + public MultiDictionary(IEqualityComparer? comparer) { dict = new Dictionary>(comparer); } diff --git a/ICSharpCode.Decompiler/Util/Platform.cs b/ICSharpCode.Decompiler/Util/Platform.cs index b91a91060..69419877c 100644 --- a/ICSharpCode.Decompiler/Util/Platform.cs +++ b/ICSharpCode.Decompiler/Util/Platform.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team +#nullable enable +// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software diff --git a/ICSharpCode.Decompiler/Util/ProjectedList.cs b/ICSharpCode.Decompiler/Util/ProjectedList.cs index fa632005e..5026f2f1c 100644 --- a/ICSharpCode.Decompiler/Util/ProjectedList.cs +++ b/ICSharpCode.Decompiler/Util/ProjectedList.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team +#nullable enable +// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -25,7 +26,7 @@ namespace ICSharpCode.Decompiler.Util { readonly IList input; readonly Func projection; - readonly TOutput[] items; + readonly TOutput?[] items; public ProjectedList(IList input, Func projection) { @@ -35,12 +36,12 @@ namespace ICSharpCode.Decompiler.Util throw new ArgumentNullException(nameof(projection)); this.input = input; this.projection = projection; - this.items = new TOutput[input.Count]; + this.items = new TOutput?[input.Count]; } public TOutput this[int index] { get { - TOutput output = LazyInit.VolatileRead(ref items[index]); + TOutput? output = LazyInit.VolatileRead(ref items[index]); if (output != null) { return output; @@ -72,7 +73,7 @@ namespace ICSharpCode.Decompiler.Util readonly IList input; readonly TContext context; readonly Func projection; - readonly TOutput[] items; + readonly TOutput?[] items; public ProjectedList(TContext context, IList input, Func projection) { @@ -83,12 +84,12 @@ namespace ICSharpCode.Decompiler.Util this.input = input; this.context = context; this.projection = projection; - this.items = new TOutput[input.Count]; + this.items = new TOutput?[input.Count]; } public TOutput this[int index] { get { - TOutput output = LazyInit.VolatileRead(ref items[index]); + TOutput? output = LazyInit.VolatileRead(ref items[index]); if (output != null) { return output; diff --git a/ICSharpCode.Decompiler/Util/ReferenceComparer.cs b/ICSharpCode.Decompiler/Util/ReferenceComparer.cs index cb4485bce..43b1e3afe 100644 --- a/ICSharpCode.Decompiler/Util/ReferenceComparer.cs +++ b/ICSharpCode.Decompiler/Util/ReferenceComparer.cs @@ -15,22 +15,23 @@ // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#nullable enable using System.Collections.Generic; using System.Runtime.CompilerServices; namespace ICSharpCode.Decompiler.Util { - public sealed class ReferenceComparer : IEqualityComparer + public sealed class ReferenceComparer : IEqualityComparer { public readonly static ReferenceComparer Instance = new ReferenceComparer(); - public new bool Equals(object x, object y) + public new bool Equals(object? x, object? y) { return x == y; } - public int GetHashCode(object obj) + public int GetHashCode(object? obj) { return RuntimeHelpers.GetHashCode(obj); } diff --git a/ICSharpCode.Decompiler/Util/ResourcesFile.cs b/ICSharpCode.Decompiler/Util/ResourcesFile.cs index a55637006..988fa01a2 100644 --- a/ICSharpCode.Decompiler/Util/ResourcesFile.cs +++ b/ICSharpCode.Decompiler/Util/ResourcesFile.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2018 Daniel Grunwald +#nullable enable +// Copyright (c) 2018 Daniel Grunwald // Based on the .NET Core ResourceReader; make available under the MIT license // by the .NET Foundation. // @@ -30,7 +31,7 @@ namespace ICSharpCode.Decompiler.Util /// /// .resources file. /// - public class ResourcesFile : IEnumerable>, IDisposable + public class ResourcesFile : IEnumerable>, IDisposable { sealed class MyBinaryReader : BinaryReader { @@ -87,7 +88,7 @@ namespace ICSharpCode.Decompiler.Util readonly long fileStartPosition; readonly long nameSectionPosition; readonly long dataSectionPosition; - long[] startPositions; + long[]? startPositions; /// /// Creates a new ResourcesFile. @@ -285,7 +286,7 @@ namespace ICSharpCode.Decompiler.Util return true; } - object LoadObject(int dataOffset) + object? LoadObject(int dataOffset) { try { @@ -318,7 +319,7 @@ namespace ICSharpCode.Decompiler.Util // from that location. // Anyone who calls LoadObject should make sure they take a lock so // no one can cause us to do a seek in here. - private object LoadObjectV1(int dataOffset) + private object? LoadObjectV1(int dataOffset) { Debug.Assert(System.Threading.Monitor.IsEntered(reader)); reader.Seek(dataSectionPosition + dataOffset, SeekOrigin.Begin); @@ -372,7 +373,7 @@ namespace ICSharpCode.Decompiler.Util } } - private object LoadObjectV2(int dataOffset) + private object? LoadObjectV2(int dataOffset) { Debug.Assert(System.Threading.Monitor.IsEntered(reader)); reader.Seek(dataSectionPosition + dataOffset, SeekOrigin.Begin); @@ -464,19 +465,19 @@ namespace ICSharpCode.Decompiler.Util } } - public object GetResourceValue(int index) + public object? GetResourceValue(int index) { GetResourceName(index, out int dataOffset); return LoadObject(dataOffset); } - public IEnumerator> GetEnumerator() + public IEnumerator> GetEnumerator() { for (int i = 0; i < numResources; i++) { string name = GetResourceName(i, out int dataOffset); - object val = LoadObject(dataOffset); - yield return new KeyValuePair(name, val); + object? val = LoadObject(dataOffset); + yield return new KeyValuePair(name, val); } } @@ -487,7 +488,7 @@ namespace ICSharpCode.Decompiler.Util long[] GetStartPositions() { - long[] positions = LazyInit.VolatileRead(ref startPositions); + long[]? positions = LazyInit.VolatileRead(ref startPositions); if (positions != null) return positions; lock (reader) @@ -541,11 +542,11 @@ namespace ICSharpCode.Decompiler.Util public class ResourceSerializedObject { - public string TypeName { get; } + public string? TypeName { get; } readonly ResourcesFile file; readonly long position; - internal ResourceSerializedObject(string typeName, ResourcesFile file, long position) + internal ResourceSerializedObject(string? typeName, ResourcesFile file, long position) { this.TypeName = typeName; this.file = file; diff --git a/ICSharpCode.Decompiler/Util/TreeTraversal.cs b/ICSharpCode.Decompiler/Util/TreeTraversal.cs index a12b35c46..f750ac137 100644 --- a/ICSharpCode.Decompiler/Util/TreeTraversal.cs +++ b/ICSharpCode.Decompiler/Util/TreeTraversal.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team +#nullable enable +// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -32,7 +33,7 @@ namespace ICSharpCode.Decompiler.Util /// The root element of the tree. /// The function that gets the children of an element. /// Iterator that enumerates the tree structure in pre-order. - public static IEnumerable PreOrder(T root, Func> recursion) + public static IEnumerable PreOrder(T root, Func?> recursion) { return PreOrder(new T[] { root }, recursion); } @@ -43,7 +44,7 @@ namespace ICSharpCode.Decompiler.Util /// The root elements of the forest. /// The function that gets the children of an element. /// Iterator that enumerates the tree structure in pre-order. - public static IEnumerable PreOrder(IEnumerable input, Func> recursion) + public static IEnumerable PreOrder(IEnumerable input, Func?> recursion) { Stack> stack = new Stack>(); try @@ -55,7 +56,7 @@ namespace ICSharpCode.Decompiler.Util { T element = stack.Peek().Current; yield return element; - IEnumerable children = recursion(element); + IEnumerable? children = recursion(element); if (children != null) { stack.Push(children.GetEnumerator()); @@ -79,7 +80,7 @@ namespace ICSharpCode.Decompiler.Util /// The root element of the tree. /// The function that gets the children of an element. /// Iterator that enumerates the tree structure in post-order. - public static IEnumerable PostOrder(T root, Func> recursion) + public static IEnumerable PostOrder(T root, Func?> recursion) { return PostOrder(new T[] { root }, recursion); } @@ -90,7 +91,7 @@ namespace ICSharpCode.Decompiler.Util /// The root elements of the forest. /// The function that gets the children of an element. /// Iterator that enumerates the tree structure in post-order. - public static IEnumerable PostOrder(IEnumerable input, Func> recursion) + public static IEnumerable PostOrder(IEnumerable input, Func?> recursion) { Stack> stack = new Stack>(); try @@ -101,7 +102,7 @@ namespace ICSharpCode.Decompiler.Util while (stack.Peek().MoveNext()) { T element = stack.Peek().Current; - IEnumerable children = recursion(element); + IEnumerable? children = recursion(element); if (children != null) { stack.Push(children.GetEnumerator()); diff --git a/ICSharpCode.Decompiler/Util/UnicodeNewline.cs b/ICSharpCode.Decompiler/Util/UnicodeNewline.cs index dca342ce0..a81824529 100644 --- a/ICSharpCode.Decompiler/Util/UnicodeNewline.cs +++ b/ICSharpCode.Decompiler/Util/UnicodeNewline.cs @@ -1,3 +1,4 @@ +#nullable enable // // UnicodeNewline.cs // @@ -118,7 +119,7 @@ namespace ICSharpCode.Decompiler.Util /// 0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter. /// The current character. /// A callback getting the next character (may be null). - public static int GetDelimiterLength(char curChar, Func nextChar = null) + public static int GetDelimiterLength(char curChar, Func? nextChar = null) { if (curChar == CR) { @@ -161,7 +162,7 @@ namespace ICSharpCode.Decompiler.Util /// The length of the delimiter /// The type of the delimiter /// A callback getting the next character (may be null). - public static bool TryGetDelimiterLengthAndType(char curChar, out int length, out UnicodeNewline type, Func nextChar = null) + public static bool TryGetDelimiterLengthAndType(char curChar, out int length, out UnicodeNewline type, Func? nextChar = null) { if (curChar == CR) { @@ -275,7 +276,7 @@ namespace ICSharpCode.Decompiler.Util /// 0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter. /// The current character. /// A callback getting the next character (may be null). - public static UnicodeNewline GetDelimiterType(char curChar, Func nextChar = null) + public static UnicodeNewline GetDelimiterType(char curChar, Func? nextChar = null) { switch (curChar) { diff --git a/ICSharpCode.Decompiler/Util/UnionFind.cs b/ICSharpCode.Decompiler/Util/UnionFind.cs index 4bc0acbdf..15c06f2d7 100644 --- a/ICSharpCode.Decompiler/Util/UnionFind.cs +++ b/ICSharpCode.Decompiler/Util/UnionFind.cs @@ -15,6 +15,7 @@ // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#nullable enable using System.Collections.Generic; @@ -32,6 +33,12 @@ namespace ICSharpCode.Decompiler.Util public int rank; public Node parent; public T value; + + internal Node(T value) + { + this.value = value; + this.parent = this; + } } public UnionFind() @@ -44,10 +51,7 @@ namespace ICSharpCode.Decompiler.Util Node node; if (!mapping.TryGetValue(element, out node)) { - node = new Node { - value = element, - rank = 0 - }; + node = new Node(element); node.parent = node; mapping.Add(element, node); } @@ -84,5 +88,3 @@ namespace ICSharpCode.Decompiler.Util } } } - - diff --git a/ICSharpCode.Decompiler/Util/Win32Resources.cs b/ICSharpCode.Decompiler/Util/Win32Resources.cs index a5adf81f4..c3574fc9b 100644 --- a/ICSharpCode.Decompiler/Util/Win32Resources.cs +++ b/ICSharpCode.Decompiler/Util/Win32Resources.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection.PortableExecutable; @@ -15,21 +16,21 @@ namespace ICSharpCode.Decompiler.Util /// /// /// - public static unsafe Win32ResourceDirectory ReadWin32Resources(this PEReader pe) + public static unsafe Win32ResourceDirectory? ReadWin32Resources(this PEReader pe) { if (pe == null) { throw new ArgumentNullException(nameof(pe)); } - int rva = pe.PEHeaders.PEHeader.ResourceTableDirectory.RelativeVirtualAddress; + int rva = pe.PEHeaders.PEHeader?.ResourceTableDirectory.RelativeVirtualAddress ?? 0; if (rva == 0) return null; byte* pRoot = pe.GetSectionData(rva).Pointer; return new Win32ResourceDirectory(pe, pRoot, 0, new Win32ResourceName("Root")); } - public static Win32ResourceDirectory Find(this Win32ResourceDirectory root, Win32ResourceName type) + public static Win32ResourceDirectory? Find(this Win32ResourceDirectory root, Win32ResourceName type) { if (root is null) throw new ArgumentNullException(nameof(root)); @@ -41,7 +42,7 @@ namespace ICSharpCode.Decompiler.Util return root.FindDirectory(type); } - public static Win32ResourceDirectory Find(this Win32ResourceDirectory root, Win32ResourceName type, Win32ResourceName name) + public static Win32ResourceDirectory? Find(this Win32ResourceDirectory root, Win32ResourceName type, Win32ResourceName name) { if (root is null) throw new ArgumentNullException(nameof(root)); @@ -55,7 +56,7 @@ namespace ICSharpCode.Decompiler.Util return root.FindDirectory(type)?.FindDirectory(name); } - public static Win32ResourceData Find(this Win32ResourceDirectory root, Win32ResourceName type, Win32ResourceName name, Win32ResourceName langId) + public static Win32ResourceData? Find(this Win32ResourceDirectory root, Win32ResourceName type, Win32ResourceName name, Win32ResourceName langId) { if (root is null) throw new ArgumentNullException(nameof(root)); @@ -122,7 +123,7 @@ namespace ICSharpCode.Decompiler.Util return new string(pString->NameString, 0, pString->Length); } - public Win32ResourceDirectory FindDirectory(Win32ResourceName name) + public Win32ResourceDirectory? FindDirectory(Win32ResourceName name) { foreach (var directory in Directories) { @@ -132,7 +133,7 @@ namespace ICSharpCode.Decompiler.Util return null; } - public Win32ResourceData FindData(Win32ResourceName name) + public Win32ResourceData? FindData(Win32ResourceName name) { foreach (var data in Datas) { @@ -142,12 +143,12 @@ namespace ICSharpCode.Decompiler.Util return null; } - public Win32ResourceDirectory FirstDirectory() + public Win32ResourceDirectory? FirstDirectory() { return Directories.Count != 0 ? Directories[0] : null; } - public Win32ResourceData FirstData() + public Win32ResourceData? FirstData() { return Datas.Count != 0 ? Datas[0] : null; } @@ -248,7 +249,7 @@ namespace ICSharpCode.Decompiler.Util return _name.GetHashCode(); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (!(obj is Win32ResourceName name)) return false; diff --git a/ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj b/ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj index 85c0519e3..1b2337cb3 100644 --- a/ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj +++ b/ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj @@ -1,5 +1,5 @@  - + net472 @@ -112,4 +112,4 @@ - \ No newline at end of file + From 5fb2f7a22fb4d830254b7162aba4d6c6f66421e3 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Thu, 3 Jun 2021 21:36:12 +0200 Subject: [PATCH 2/6] #nullable enable for ILAst (except for generated code) --- .../CSharp/Resolver/CSharpOperators.cs | 4 +- .../IL/ILAstWritingOptions.cs | 7 +- .../IL/ILInstructionExtensions.cs | 5 +- ICSharpCode.Decompiler/IL/ILTypeExtensions.cs | 7 +- ICSharpCode.Decompiler/IL/ILVariable.cs | 20 ++--- ICSharpCode.Decompiler/IL/InstructionFlags.cs | 3 +- .../IL/InstructionOutputExtensions.cs | 3 +- .../IL/Instructions/Await.cs | 7 +- .../Instructions/BinaryNumericInstruction.cs | 5 +- .../IL/Instructions/Block.cs | 41 +++++----- .../IL/Instructions/BlockContainer.cs | 32 ++++---- .../IL/Instructions/Branch.cs | 25 ++++--- .../IL/Instructions/CallIndirect.cs | 5 +- .../IL/Instructions/CallInstruction.cs | 15 ++-- .../IL/Instructions/Comp.cs | 6 +- .../CompoundAssignmentInstruction.cs | 5 +- .../IL/Instructions/Conv.cs | 3 +- .../DeconstructResultInstruction.cs | 9 ++- .../IL/Instructions/DefaultValue.cs | 3 +- .../IL/Instructions/DynamicInstructions.cs | 41 +++++----- .../IL/Instructions/ExpressionTreeCast.cs | 3 +- .../IL/Instructions/ILFunction.cs | 30 ++++---- .../IL/Instructions/ILInstruction.cs | 2 +- .../IL/Instructions/ILVariableCollection.cs | 5 +- .../IL/Instructions/IfInstruction.cs | 9 ++- .../IL/Instructions/LdFlda.cs | 3 +- .../IL/Instructions/LdLen.cs | 3 +- .../IL/Instructions/Leave.cs | 13 ++-- .../IL/Instructions/LockInstruction.cs | 3 +- .../IL/Instructions/LogicInstructions.cs | 3 +- .../IL/Instructions/MatchInstruction.cs | 14 ++-- .../IL/Instructions/MemoryInstructions.cs | 3 +- .../Instructions/NullCoalescingInstruction.cs | 3 +- .../IL/Instructions/NullableInstructions.cs | 3 +- .../IL/Instructions/PatternMatching.cs | 75 ++++++++++--------- .../IL/Instructions/SimpleInstruction.cs | 13 ++-- .../IL/Instructions/StLoc.cs | 7 +- .../IL/Instructions/StringToInt.cs | 13 ++-- .../IL/Instructions/SwitchInstruction.cs | 4 +- .../IL/Instructions/TryInstruction.cs | 11 +-- .../IL/Instructions/UnaryInstruction.cs | 3 +- .../IL/Instructions/UsingInstruction.cs | 3 +- ICSharpCode.Decompiler/IL/Patterns/AnyNode.cs | 16 ++-- .../IL/Patterns/ListMatch.cs | 13 ++-- ICSharpCode.Decompiler/IL/Patterns/Match.cs | 5 +- ICSharpCode.Decompiler/IL/PrimitiveType.cs | 3 +- ICSharpCode.Decompiler/IL/SemanticHelper.cs | 4 +- ICSharpCode.Decompiler/IL/SlotInfo.cs | 1 + ICSharpCode.Decompiler/IL/StackType.cs | 1 + ICSharpCode.Decompiler/TypeSystem/IMember.cs | 6 ++ .../Implementation/SyntheticRangeIndexer.cs | 2 +- 51 files changed, 286 insertions(+), 237 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/Resolver/CSharpOperators.cs b/ICSharpCode.Decompiler/CSharp/Resolver/CSharpOperators.cs index 2064c1f52..1bfef1ecf 100644 --- a/ICSharpCode.Decompiler/CSharp/Resolver/CSharpOperators.cs +++ b/ICSharpCode.Decompiler/CSharp/Resolver/CSharpOperators.cs @@ -128,9 +128,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver get { return null; } } - IType IEntity.DeclaringType { - get { return null; } - } + public IType DeclaringType => SpecialType.UnknownType; IMember IMember.MemberDefinition { get { return this; } diff --git a/ICSharpCode.Decompiler/IL/ILAstWritingOptions.cs b/ICSharpCode.Decompiler/IL/ILAstWritingOptions.cs index 90c7aaca8..ce49f34df 100644 --- a/ICSharpCode.Decompiler/IL/ILAstWritingOptions.cs +++ b/ICSharpCode.Decompiler/IL/ILAstWritingOptions.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2017 Daniel Grunwald +#nullable enable +// Copyright (c) 2017 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -84,7 +85,7 @@ namespace ICSharpCode.Decompiler.IL } } - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } @@ -94,6 +95,6 @@ namespace ICSharpCode.Decompiler.IL PropertyChanged?.Invoke(this, e); } - public event PropertyChangedEventHandler PropertyChanged; + public event PropertyChangedEventHandler? PropertyChanged; } } diff --git a/ICSharpCode.Decompiler/IL/ILInstructionExtensions.cs b/ICSharpCode.Decompiler/IL/ILInstructionExtensions.cs index 6f6ec269f..de6d3d972 100644 --- a/ICSharpCode.Decompiler/IL/ILInstructionExtensions.cs +++ b/ICSharpCode.Decompiler/IL/ILInstructionExtensions.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; using System.Text; @@ -20,7 +21,7 @@ namespace ICSharpCode.Decompiler.IL return target; } - public static ILInstruction GetNextSibling(this ILInstruction instruction) + public static ILInstruction? GetNextSibling(this ILInstruction? instruction) { if (instruction?.Parent == null) return null; diff --git a/ICSharpCode.Decompiler/IL/ILTypeExtensions.cs b/ICSharpCode.Decompiler/IL/ILTypeExtensions.cs index feac446f4..5b5767f3b 100644 --- a/ICSharpCode.Decompiler/IL/ILTypeExtensions.cs +++ b/ICSharpCode.Decompiler/IL/ILTypeExtensions.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -145,12 +146,12 @@ namespace ICSharpCode.Decompiler.IL /// /// Returns SpecialType.UnknownType for unsupported instructions. /// - public static IType InferType(this ILInstruction inst, ICompilation compilation) + public static IType InferType(this ILInstruction inst, ICompilation? compilation) { switch (inst) { case NewObj newObj: - return newObj.Method.DeclaringType; + return newObj.Method.DeclaringType ?? SpecialType.UnknownType; case NewArr newArr: if (compilation != null) return new ArrayType(compilation, newArr.Type, newArr.Indices.Count); diff --git a/ICSharpCode.Decompiler/IL/ILVariable.cs b/ICSharpCode.Decompiler/IL/ILVariable.cs index b162d2526..07dee70ef 100644 --- a/ICSharpCode.Decompiler/IL/ILVariable.cs +++ b/ICSharpCode.Decompiler/IL/ILVariable.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -19,7 +20,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using ICSharpCode.Decompiler.TypeSystem; @@ -192,7 +192,7 @@ namespace ICSharpCode.Decompiler.IL } } - public string Name { get; set; } + public string? Name { get; set; } public bool HasGeneratedName { get; set; } @@ -202,7 +202,7 @@ namespace ICSharpCode.Decompiler.IL /// /// This property is set automatically when the variable is added to the ILFunction.Variables collection. /// - public ILFunction Function { get; internal set; } + public ILFunction? Function { get; internal set; } /// /// Gets the block container in which this variable is captured. @@ -212,7 +212,7 @@ namespace ICSharpCode.Decompiler.IL /// /// This property returns null for variables that are not captured. /// - public BlockContainer CaptureScope { get; internal set; } + public BlockContainer? CaptureScope { get; internal set; } /// /// Gets the index of this variable within the Function.Variables collection. @@ -309,7 +309,7 @@ namespace ICSharpCode.Decompiler.IL return list.Count - 1; } - void RemoveInstruction(List list, int index, T inst) where T : class, IInstructionWithVariableOperand + void RemoveInstruction(List list, int index, T? inst) where T : class, IInstructionWithVariableOperand { Debug.Assert(list[index] == inst); int indexToMove = list.Count - 1; @@ -370,7 +370,7 @@ namespace ICSharpCode.Decompiler.IL /// The field which was converted to a local variable. /// Set when the variable is from a 'yield return' or 'async' state machine. /// - public IField StateMachineField; + public IField? StateMachineField; public ILVariable(VariableKind kind, IType type, int? index = null) { @@ -398,7 +398,7 @@ namespace ICSharpCode.Decompiler.IL CheckInvariant(); } - public override string ToString() + public override string? ToString() { return Name; } @@ -472,7 +472,7 @@ namespace ICSharpCode.Decompiler.IL if (CaptureScope != null) { output.Write(" captured in "); - output.WriteLocalReference(CaptureScope.EntryPoint.Label, CaptureScope); + output.WriteLocalReference(CaptureScope.EntryPoint?.Label, CaptureScope); } if (StateMachineField != null) { @@ -528,7 +528,7 @@ namespace ICSharpCode.Decompiler.IL { public static readonly ILVariableEqualityComparer Instance = new ILVariableEqualityComparer(); - public bool Equals(ILVariable x, ILVariable y) + public bool Equals(ILVariable? x, ILVariable? y) { if (x == y) return true; diff --git a/ICSharpCode.Decompiler/IL/InstructionFlags.cs b/ICSharpCode.Decompiler/IL/InstructionFlags.cs index 49f7ff1b8..e0fcf9f47 100644 --- a/ICSharpCode.Decompiler/IL/InstructionFlags.cs +++ b/ICSharpCode.Decompiler/IL/InstructionFlags.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software diff --git a/ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs b/ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs index c1f7a1715..b5f857cf1 100644 --- a/ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs +++ b/ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software diff --git a/ICSharpCode.Decompiler/IL/Instructions/Await.cs b/ICSharpCode.Decompiler/IL/Instructions/Await.cs index 211df8b01..39816767c 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Await.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Await.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2017 Daniel Grunwald +#nullable enable +// Copyright (c) 2017 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -22,7 +23,7 @@ namespace ICSharpCode.Decompiler.IL { partial class Await { - public IMethod GetAwaiterMethod; - public IMethod GetResultMethod; + public IMethod? GetAwaiterMethod; + public IMethod? GetResultMethod; } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs index 2ab7ceef8..2d87e1b4a 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -214,5 +215,3 @@ namespace ICSharpCode.Decompiler.IL } } } - - diff --git a/ICSharpCode.Decompiler/IL/Instructions/Block.cs b/ICSharpCode.Decompiler/IL/Instructions/Block.cs index 8fbf81816..11e1b1d33 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Block.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Block.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014-2016 Daniel Grunwald +#nullable enable +// Copyright (c) 2014-2016 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -16,14 +17,13 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using ICSharpCode.Decompiler.IL.Transforms; using ICSharpCode.Decompiler.TypeSystem; - namespace ICSharpCode.Decompiler.IL { /// @@ -48,7 +48,7 @@ namespace ICSharpCode.Decompiler.IL public readonly BlockKind Kind; public readonly InstructionCollection Instructions; - ILInstruction finalInstruction; + ILInstruction finalInstruction = null!; /// /// For blocks in a block container, this field holds @@ -125,7 +125,7 @@ namespace ICSharpCode.Decompiler.IL { var stloc = inst as StLoc; Debug.Assert(stloc != null, "Instructions in CallWithNamedArgs must be assignments"); - Debug.Assert(stloc.Variable.Kind == VariableKind.NamedArgument); + Debug.Assert(stloc!.Variable.Kind == VariableKind.NamedArgument); Debug.Assert(stloc.Variable.IsSingleDefinition && stloc.Variable.LoadCount == 1); Debug.Assert(stloc.Variable.LoadInstructions.Single().Parent == finalInstruction); } @@ -140,22 +140,22 @@ namespace ICSharpCode.Decompiler.IL case BlockKind.ArrayInitializer: var final = finalInstruction as LdLoc; Debug.Assert(final != null && final.Variable.IsSingleDefinition && final.Variable.Kind == VariableKind.InitializerTarget); - IType type = null; - Debug.Assert(Instructions[0].MatchStLoc(final.Variable, out var init) && init.MatchNewArr(out type)); + IType? type = null; + Debug.Assert(Instructions[0].MatchStLoc(final!.Variable, out var init) && init.MatchNewArr(out type)); for (int i = 1; i < Instructions.Count; i++) { - Debug.Assert(Instructions[i].MatchStObj(out ILInstruction target, out _, out var t) && type != null && type.Equals(t)); - Debug.Assert(target.MatchLdElema(out t, out ILInstruction array) && type.Equals(t)); - Debug.Assert(array.MatchLdLoc(out ILVariable v) && v == final.Variable); + Debug.Assert(Instructions[i].MatchStObj(out ILInstruction? target, out _, out var t) && type != null && type.Equals(t)); + Debug.Assert(target.MatchLdElema(out t, out ILInstruction? array) && type!.Equals(t)); + Debug.Assert(array.MatchLdLoc(out ILVariable? v) && v == final.Variable); } break; case BlockKind.CollectionInitializer: case BlockKind.ObjectInitializer: var final2 = finalInstruction as LdLoc; Debug.Assert(final2 != null); - var initVar2 = final2.Variable; + var initVar2 = final2!.Variable; Debug.Assert(initVar2.StoreCount == 1 && initVar2.Kind == VariableKind.InitializerTarget); - IType type2 = null; + IType? type2 = null; bool condition = Instructions[0].MatchStLoc(final2.Variable, out var init2); Debug.Assert(condition); Debug.Assert(init2 is NewObj @@ -300,7 +300,7 @@ namespace ICSharpCode.Decompiler.IL public void Remove() { Debug.Assert(ChildIndex > 0); - var container = (BlockContainer)Parent; + var container = (BlockContainer)Parent!; Debug.Assert(container.Blocks[ChildIndex] == this); container.Blocks.SwapRemoveAt(ChildIndex); } @@ -325,7 +325,7 @@ namespace ICSharpCode.Decompiler.IL /// Gets the predecessor of the given instruction. /// Returns null if inst.Parent is not a block. /// - public static ILInstruction GetPredecessor(ILInstruction inst) + public static ILInstruction? GetPredecessor(ILInstruction inst) { if (inst.Parent is Block block && inst.ChildIndex > 0) { @@ -341,7 +341,8 @@ namespace ICSharpCode.Decompiler.IL /// If inst is a block consisting of a single instruction, returns that instruction. /// Otherwise, returns the input instruction. /// - public static ILInstruction Unwrap(ILInstruction inst) + [return: NotNullIfNotNull("inst")] + public static ILInstruction? Unwrap(ILInstruction? inst) { if (inst is Block block) { @@ -355,19 +356,19 @@ namespace ICSharpCode.Decompiler.IL /// Gets the closest parent Block. /// Returns null, if the instruction is not a descendant of a Block. /// - public static Block FindClosestBlock(ILInstruction inst) + public static Block? FindClosestBlock(ILInstruction? inst) { var curr = inst; while (curr != null) { - if (curr is Block) - return (Block)curr; + if (curr is Block b) + return b; curr = curr.Parent; } return null; } - public bool MatchInlineAssignBlock(out CallInstruction call, out ILInstruction value) + public bool MatchInlineAssignBlock([NotNullWhen(true)] out CallInstruction? call, [NotNullWhen(true)] out ILInstruction? value) { call = null; value = null; @@ -385,7 +386,7 @@ namespace ICSharpCode.Decompiler.IL return this.FinalInstruction.MatchLdLoc(tmp); } - public bool MatchIfAtEndOfBlock(out ILInstruction condition, out ILInstruction trueInst, out ILInstruction falseInst) + public bool MatchIfAtEndOfBlock([NotNullWhen(true)] out ILInstruction? condition, [NotNullWhen(true)] out ILInstruction? trueInst, [NotNullWhen(true)] out ILInstruction? falseInst) { condition = null; trueInst = null; diff --git a/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs b/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs index 609e1386b..0330f079f 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -19,11 +20,11 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using ICSharpCode.Decompiler.IL.Transforms; using ICSharpCode.Decompiler.Util; - namespace ICSharpCode.Decompiler.IL { /// @@ -57,13 +58,18 @@ namespace ICSharpCode.Decompiler.IL } } - Block entryPoint; + Block? entryPoint; /// /// Gets the container's entry point. This is the first block in the Blocks collection. /// public Block EntryPoint { - get { return entryPoint; } + get { + // HACK: While it's possible to have BlockContainers without entry point, + // normally every container must have an entry point according to its invariant. + // Thus it's easier on the transforms if this property returns a non-nullable EntryPoint. + return entryPoint!; + } private set { if (entryPoint != null && IsConnected) entryPoint.IncomingEdgeCount--; @@ -102,7 +108,7 @@ namespace ICSharpCode.Decompiler.IL protected internal override void InstructionCollectionUpdateComplete() { base.InstructionCollectionUpdateComplete(); - this.EntryPoint = this.Blocks.FirstOrDefault(); + this.EntryPoint = this.Blocks.FirstOrDefault()!; } protected override void Connected() @@ -174,7 +180,7 @@ namespace ICSharpCode.Decompiler.IL return Blocks[index]; } - protected override void SetChild(int index, ILInstruction value) + protected override void SetChild(int index, ILInstruction? value) { if (Blocks[index] != value) throw new InvalidOperationException("Cannot replace blocks in BlockContainer"); @@ -189,12 +195,12 @@ namespace ICSharpCode.Decompiler.IL { base.CheckInvariant(phase); Debug.Assert(Blocks.Count > 0 && EntryPoint == Blocks[0]); - Debug.Assert(!IsConnected || EntryPoint?.IncomingEdgeCount >= 1); - Debug.Assert(EntryPoint == null || Parent is ILFunction || !ILRangeIsEmpty); + Debug.Assert(!IsConnected || EntryPoint.IncomingEdgeCount >= 1); + Debug.Assert(Parent is ILFunction || !ILRangeIsEmpty); Debug.Assert(Blocks.All(b => b.HasFlag(InstructionFlags.EndPointUnreachable))); Debug.Assert(Blocks.All(b => b.Kind == BlockKind.ControlFlow)); // this also implies that the blocks don't use FinalInstruction Debug.Assert(TopologicalSort(deleteUnreachableBlocks: true).Count == Blocks.Count, "Container should not have any unreachable blocks"); - Block bodyStartBlock; + Block? bodyStartBlock; switch (Kind) { case ContainerKind.Normal: @@ -319,7 +325,7 @@ namespace ICSharpCode.Decompiler.IL Blocks.ReplaceList(newOrder); } - public static BlockContainer FindClosestContainer(ILInstruction inst) + public static BlockContainer? FindClosestContainer(ILInstruction? inst) { while (inst != null) { @@ -330,18 +336,18 @@ namespace ICSharpCode.Decompiler.IL return null; } - public static BlockContainer FindClosestSwitchContainer(ILInstruction inst) + public static BlockContainer? FindClosestSwitchContainer(ILInstruction? inst) { while (inst != null) { - if (inst is BlockContainer bc && bc.entryPoint.Instructions.FirstOrDefault() is SwitchInstruction) + if (inst is BlockContainer { Kind: ContainerKind.Switch } bc) return bc; inst = inst.Parent; } return null; } - public bool MatchConditionBlock(Block block, out ILInstruction condition, out Block bodyStartBlock) + public bool MatchConditionBlock(Block block, [NotNullWhen(true)] out ILInstruction? condition, [NotNullWhen(true)] out Block? bodyStartBlock) { condition = null; bodyStartBlock = null; diff --git a/ICSharpCode.Decompiler/IL/Instructions/Branch.cs b/ICSharpCode.Decompiler/IL/Instructions/Branch.cs index 4eda178cb..b18daa170 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Branch.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Branch.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -30,7 +31,7 @@ namespace ICSharpCode.Decompiler.IL partial class Branch : SimpleInstruction, IBranchOrLeaveInstruction { readonly int targetILOffset; - Block targetBlock; + Block? targetBlock; public Branch(int targetILOffset) : base(OpCode.Branch) { @@ -48,7 +49,11 @@ namespace ICSharpCode.Decompiler.IL } public Block TargetBlock { - get { return targetBlock; } + get { + // HACK: We treat TargetBlock as non-nullable publicly, because it's only null inside + // the ILReader, and becomes non-null once the BlockBuilder has run. + return targetBlock!; + } set { if (targetBlock != null && IsConnected) targetBlock.IncomingEdgeCount--; @@ -62,7 +67,7 @@ namespace ICSharpCode.Decompiler.IL /// Gets the BlockContainer that contains the target block. /// public BlockContainer TargetContainer { - get { return (BlockContainer)targetBlock?.Parent; } + get { return (BlockContainer)targetBlock?.Parent!; } } protected override void Connected() @@ -92,9 +97,9 @@ namespace ICSharpCode.Decompiler.IL } } - internal static bool GetExecutesFinallyBlock(ILInstruction inst, BlockContainer container) + internal static bool GetExecutesFinallyBlock(ILInstruction? inst, BlockContainer? container) { - for (; inst != container; inst = inst.Parent) + for (; inst != container && inst != null; inst = inst.Parent) { if (inst.Parent is TryFinally && inst.SlotInfo == TryFinally.TryBlockSlot) return true; @@ -107,9 +112,9 @@ namespace ICSharpCode.Decompiler.IL base.CheckInvariant(phase); if (phase > ILPhase.InILReader) { - Debug.Assert(targetBlock.Parent is BlockContainer); - Debug.Assert(this.IsDescendantOf(targetBlock.Parent)); - Debug.Assert(targetBlock.Parent.Children[targetBlock.ChildIndex] == targetBlock); + Debug.Assert(targetBlock?.Parent is BlockContainer); + Debug.Assert(this.IsDescendantOf(targetBlock!.Parent!)); + Debug.Assert(targetBlock!.Parent!.Children[targetBlock.ChildIndex] == targetBlock); } } @@ -118,7 +123,7 @@ namespace ICSharpCode.Decompiler.IL WriteILRange(output, options); output.Write(OpCode); output.Write(' '); - output.WriteLocalReference(TargetLabel, (object)targetBlock ?? TargetILOffset); + output.WriteLocalReference(TargetLabel, (object?)targetBlock ?? TargetILOffset); } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs b/ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs index a12592d06..94a14ee03 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2017 Daniel Grunwald +#nullable enable +// Copyright (c) 2017 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -31,7 +32,7 @@ namespace ICSharpCode.Decompiler.IL public static readonly SlotInfo FunctionPointerSlot = new SlotInfo("FunctionPointer", canInlineInto: true); public static readonly SlotInfo ArgumentSlot = new SlotInfo("Argument", canInlineInto: true, isCollection: true); - ILInstruction functionPointer; + ILInstruction functionPointer = null!; public readonly InstructionCollection Arguments; public bool IsInstance { get; } public bool HasExplicitThis { get; } diff --git a/ICSharpCode.Decompiler/IL/Instructions/CallInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/CallInstruction.cs index 6e87d9c4e..ccdf1f5fa 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/CallInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/CallInstruction.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -19,7 +20,6 @@ using System; using System.Diagnostics; -using ICSharpCode.Decompiler.Disassembler; using ICSharpCode.Decompiler.TypeSystem; namespace ICSharpCode.Decompiler.IL @@ -52,7 +52,7 @@ namespace ICSharpCode.Decompiler.IL /// Gets/Sets the type specified in the 'constrained.' prefix. /// Returns null if no 'constrained.' prefix exists for this call. /// - public IType ConstrainedTo; + public IType? ConstrainedTo; /// /// Gets whether the IL stack was empty at the point of this call. @@ -62,8 +62,7 @@ namespace ICSharpCode.Decompiler.IL protected CallInstruction(OpCode opCode, IMethod method) : base(opCode) { - Debug.Assert(method != null); - this.Method = method; + this.Method = method ?? throw new ArgumentNullException(nameof(method)); this.Arguments = new InstructionCollection(this, 0); } @@ -78,7 +77,7 @@ namespace ICSharpCode.Decompiler.IL /// Gets the parameter for the argument with the specified index. /// Returns null for the this parameter. /// - public IParameter GetParameter(int argumentIndex) + public IParameter? GetParameter(int argumentIndex) { int firstParamIndex = (Method.IsStatic || OpCode == OpCode.NewObj) ? 0 : 1; if (argumentIndex < firstParamIndex) @@ -160,9 +159,9 @@ namespace ICSharpCode.Decompiler.IL output.Write(')'); } - protected internal sealed override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal sealed override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { - CallInstruction o = other as CallInstruction; + CallInstruction? o = other as CallInstruction; return o != null && this.OpCode == o.OpCode && this.Method.Equals(o.Method) && this.IsTail == o.IsTail && object.Equals(this.ConstrainedTo, o.ConstrainedTo) && Patterns.ListMatch.DoMatch(this.Arguments, o.Arguments, ref match); diff --git a/ICSharpCode.Decompiler/IL/Instructions/Comp.cs b/ICSharpCode.Decompiler/IL/Instructions/Comp.cs index 21c8a6f37..227eef95c 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Comp.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Comp.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -21,7 +22,6 @@ using System.Diagnostics; using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.TypeSystem; -using ICSharpCode.Decompiler.Util; namespace ICSharpCode.Decompiler.IL { @@ -231,5 +231,3 @@ namespace ICSharpCode.Decompiler.IL } } } - - diff --git a/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs index fb5723db2..c35f986e0 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2016 Siegfried Pammer +#nullable enable +// Copyright (c) 2016 Siegfried Pammer // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -172,7 +173,7 @@ namespace ICSharpCode.Decompiler.IL /// /// Gets whether the specific binary instruction is compatible with a compound operation on the specified type. /// - internal static bool IsBinaryCompatibleWithType(BinaryNumericInstruction binary, IType type, DecompilerSettings settings) + internal static bool IsBinaryCompatibleWithType(BinaryNumericInstruction binary, IType type, DecompilerSettings? settings) { if (binary.IsLifted) { diff --git a/ICSharpCode.Decompiler/IL/Instructions/Conv.cs b/ICSharpCode.Decompiler/IL/Instructions/Conv.cs index 703fc995f..f440e7f19 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Conv.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Conv.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software diff --git a/ICSharpCode.Decompiler/IL/Instructions/DeconstructResultInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/DeconstructResultInstruction.cs index 2a6ed9655..5d04588e7 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/DeconstructResultInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/DeconstructResultInstruction.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2020 Siegfried Pammer +#nullable enable +// Copyright (c) 2020 Siegfried Pammer // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -47,9 +48,9 @@ namespace ICSharpCode.Decompiler.IL output.Write(')'); } - MatchInstruction FindMatch() + MatchInstruction? FindMatch() { - for (ILInstruction inst = this; inst != null; inst = inst.Parent) + for (ILInstruction? inst = this; inst != null; inst = inst.Parent) { if (inst.Parent is MatchInstruction match && inst != match.TestedOperand) return match; @@ -61,7 +62,7 @@ namespace ICSharpCode.Decompiler.IL { var matchInst = FindMatch(); Debug.Assert(matchInst != null && (matchInst.IsDeconstructCall || matchInst.IsDeconstructTuple)); - Debug.Assert(Argument.MatchLdLoc(matchInst.Variable)); + Debug.Assert(Argument.MatchLdLoc(matchInst!.Variable)); var outParamType = matchInst.GetDeconstructResultType(this.Index); Debug.Assert(outParamType.GetStackType() == ResultType); } diff --git a/ICSharpCode.Decompiler/IL/Instructions/DefaultValue.cs b/ICSharpCode.Decompiler/IL/Instructions/DefaultValue.cs index b8ecea156..38eb1c4b5 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/DefaultValue.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/DefaultValue.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2017 Siegfried Pammer +#nullable enable +// Copyright (c) 2017 Siegfried Pammer // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software diff --git a/ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs b/ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs index 537475072..09e116b19 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2018 Siegfried Pammer +#nullable enable +// Copyright (c) 2018 Siegfried Pammer // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -56,7 +57,7 @@ namespace ICSharpCode.Decompiler.IL public struct CSharpArgumentInfo { - public string Name { get; set; } + public string? Name { get; set; } public CSharpArgumentInfoFlags Flags { get; set; } public IType CompileTimeType { get; set; } @@ -66,9 +67,9 @@ namespace ICSharpCode.Decompiler.IL partial class DynamicInstruction { public CSharpBinderFlags BinderFlags { get; } - public IType CallingContext { get; } + public IType? CallingContext { get; } - protected DynamicInstruction(OpCode opCode, CSharpBinderFlags binderFlags, IType context) + protected DynamicInstruction(OpCode opCode, CSharpBinderFlags binderFlags, IType? context) : base(opCode) { BinderFlags = binderFlags; @@ -141,7 +142,7 @@ namespace ICSharpCode.Decompiler.IL output.Write(')'); } - public DynamicConvertInstruction(CSharpBinderFlags binderFlags, IType type, IType context, ILInstruction argument) + public DynamicConvertInstruction(CSharpBinderFlags binderFlags, IType type, IType? context, ILInstruction argument) : base(OpCode.DynamicConvertInstruction, binderFlags, context) { Type = type; @@ -171,7 +172,7 @@ namespace ICSharpCode.Decompiler.IL public IReadOnlyList TypeArguments { get; } public IReadOnlyList ArgumentInfo { get; } - public DynamicInvokeMemberInstruction(CSharpBinderFlags binderFlags, string name, IType[] typeArguments, IType context, CSharpArgumentInfo[] argumentInfo, ILInstruction[] arguments) + public DynamicInvokeMemberInstruction(CSharpBinderFlags binderFlags, string name, IType[]? typeArguments, IType? context, CSharpArgumentInfo[] argumentInfo, ILInstruction[] arguments) : base(OpCode.DynamicInvokeMemberInstruction, binderFlags, context) { Name = name; @@ -216,10 +217,10 @@ namespace ICSharpCode.Decompiler.IL partial class DynamicGetMemberInstruction { - public string Name { get; } + public string? Name { get; } public CSharpArgumentInfo TargetArgumentInfo { get; } - public DynamicGetMemberInstruction(CSharpBinderFlags binderFlags, string name, IType context, CSharpArgumentInfo targetArgumentInfo, ILInstruction target) + public DynamicGetMemberInstruction(CSharpBinderFlags binderFlags, string? name, IType? context, CSharpArgumentInfo targetArgumentInfo, ILInstruction target) : base(OpCode.DynamicGetMemberInstruction, binderFlags, context) { Name = name; @@ -249,11 +250,11 @@ namespace ICSharpCode.Decompiler.IL partial class DynamicSetMemberInstruction { - public string Name { get; } + public string? Name { get; } public CSharpArgumentInfo TargetArgumentInfo { get; } public CSharpArgumentInfo ValueArgumentInfo { get; } - public DynamicSetMemberInstruction(CSharpBinderFlags binderFlags, string name, IType context, CSharpArgumentInfo targetArgumentInfo, ILInstruction target, CSharpArgumentInfo valueArgumentInfo, ILInstruction value) + public DynamicSetMemberInstruction(CSharpBinderFlags binderFlags, string? name, IType? context, CSharpArgumentInfo targetArgumentInfo, ILInstruction target, CSharpArgumentInfo valueArgumentInfo, ILInstruction value) : base(OpCode.DynamicSetMemberInstruction, binderFlags, context) { Name = name; @@ -293,7 +294,7 @@ namespace ICSharpCode.Decompiler.IL { public IReadOnlyList ArgumentInfo { get; } - public DynamicGetIndexInstruction(CSharpBinderFlags binderFlags, IType context, CSharpArgumentInfo[] argumentInfo, ILInstruction[] arguments) + public DynamicGetIndexInstruction(CSharpBinderFlags binderFlags, IType? context, CSharpArgumentInfo[] argumentInfo, ILInstruction[] arguments) : base(OpCode.DynamicGetIndexInstruction, binderFlags, context) { ArgumentInfo = argumentInfo; @@ -325,7 +326,7 @@ namespace ICSharpCode.Decompiler.IL { public IReadOnlyList ArgumentInfo { get; } - public DynamicSetIndexInstruction(CSharpBinderFlags binderFlags, IType context, CSharpArgumentInfo[] argumentInfo, ILInstruction[] arguments) + public DynamicSetIndexInstruction(CSharpBinderFlags binderFlags, IType? context, CSharpArgumentInfo[] argumentInfo, ILInstruction[] arguments) : base(OpCode.DynamicSetIndexInstruction, binderFlags, context) { ArgumentInfo = argumentInfo; @@ -355,11 +356,11 @@ namespace ICSharpCode.Decompiler.IL partial class DynamicInvokeConstructorInstruction { - readonly IType resultType; + readonly IType? resultType; public IReadOnlyList ArgumentInfo { get; } - public DynamicInvokeConstructorInstruction(CSharpBinderFlags binderFlags, IType type, IType context, CSharpArgumentInfo[] argumentInfo, ILInstruction[] arguments) + public DynamicInvokeConstructorInstruction(CSharpBinderFlags binderFlags, IType? type, IType? context, CSharpArgumentInfo[] argumentInfo, ILInstruction[] arguments) : base(OpCode.DynamicInvokeConstructorInstruction, binderFlags, context) { ArgumentInfo = argumentInfo; @@ -395,7 +396,7 @@ namespace ICSharpCode.Decompiler.IL public CSharpArgumentInfo RightArgumentInfo { get; } public ExpressionType Operation { get; } - public DynamicBinaryOperatorInstruction(CSharpBinderFlags binderFlags, ExpressionType operation, IType context, CSharpArgumentInfo leftArgumentInfo, ILInstruction left, CSharpArgumentInfo rightArgumentInfo, ILInstruction right) + public DynamicBinaryOperatorInstruction(CSharpBinderFlags binderFlags, ExpressionType operation, IType? context, CSharpArgumentInfo leftArgumentInfo, ILInstruction left, CSharpArgumentInfo rightArgumentInfo, ILInstruction right) : base(OpCode.DynamicBinaryOperatorInstruction, binderFlags, context) { Operation = operation; @@ -437,7 +438,7 @@ namespace ICSharpCode.Decompiler.IL public CSharpArgumentInfo RightArgumentInfo { get; } public ExpressionType Operation { get; } - public DynamicLogicOperatorInstruction(CSharpBinderFlags binderFlags, ExpressionType operation, IType context, CSharpArgumentInfo leftArgumentInfo, ILInstruction left, CSharpArgumentInfo rightArgumentInfo, ILInstruction right) + public DynamicLogicOperatorInstruction(CSharpBinderFlags binderFlags, ExpressionType operation, IType? context, CSharpArgumentInfo leftArgumentInfo, ILInstruction left, CSharpArgumentInfo rightArgumentInfo, ILInstruction right) : base(OpCode.DynamicLogicOperatorInstruction, binderFlags, context) { Operation = operation; @@ -486,7 +487,7 @@ namespace ICSharpCode.Decompiler.IL public CSharpArgumentInfo OperandArgumentInfo { get; } public ExpressionType Operation { get; } - public DynamicUnaryOperatorInstruction(CSharpBinderFlags binderFlags, ExpressionType operation, IType context, CSharpArgumentInfo operandArgumentInfo, ILInstruction operand) + public DynamicUnaryOperatorInstruction(CSharpBinderFlags binderFlags, ExpressionType operation, IType? context, CSharpArgumentInfo operandArgumentInfo, ILInstruction operand) : base(OpCode.DynamicUnaryOperatorInstruction, binderFlags, context) { Operation = operation; @@ -533,7 +534,7 @@ namespace ICSharpCode.Decompiler.IL { public IReadOnlyList ArgumentInfo { get; } - public DynamicInvokeInstruction(CSharpBinderFlags binderFlags, IType context, CSharpArgumentInfo[] argumentInfo, ILInstruction[] arguments) + public DynamicInvokeInstruction(CSharpBinderFlags binderFlags, IType? context, CSharpArgumentInfo[] argumentInfo, ILInstruction[] arguments) : base(OpCode.DynamicInvokeInstruction, binderFlags, context) { ArgumentInfo = argumentInfo; @@ -562,9 +563,9 @@ namespace ICSharpCode.Decompiler.IL partial class DynamicIsEventInstruction { - public string Name { get; } + public string? Name { get; } - public DynamicIsEventInstruction(CSharpBinderFlags binderFlags, string name, IType context, ILInstruction argument) + public DynamicIsEventInstruction(CSharpBinderFlags binderFlags, string? name, IType? context, ILInstruction argument) : base(OpCode.DynamicIsEventInstruction, binderFlags, context) { Name = name; diff --git a/ICSharpCode.Decompiler/IL/Instructions/ExpressionTreeCast.cs b/ICSharpCode.Decompiler/IL/Instructions/ExpressionTreeCast.cs index 5b963f4e0..c5684cc62 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ExpressionTreeCast.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/ExpressionTreeCast.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; using System.Text; diff --git a/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs b/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs index f372c88b5..ca90cd4b0 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -18,7 +19,6 @@ using System; using System.Collections.Generic; -using System.Collections.Immutable; using System.Diagnostics; using System.Linq; @@ -35,7 +35,7 @@ namespace ICSharpCode.Decompiler.IL /// May be null for functions that were not constructed from metadata, /// e.g., expression trees. /// - public readonly IMethod Method; + public readonly IMethod? Method; /// /// Gets the generic context of this function. @@ -54,7 +54,7 @@ namespace ICSharpCode.Decompiler.IL /// has no effect, as the name should not be used in the final AST construction. /// /// - public string Name; + public string? Name; /// /// Size of the IL code in this function. @@ -71,7 +71,7 @@ namespace ICSharpCode.Decompiler.IL /// Gets the scope in which the local function is declared. /// Returns null, if this is not a local function. /// - public BlockContainer DeclarationScope { get; internal set; } + public BlockContainer? DeclarationScope { get; internal set; } /// /// Gets the set of captured variables by this ILFunction. @@ -108,17 +108,17 @@ namespace ICSharpCode.Decompiler.IL /// Return element type -- if the async method returns Task{T}, this field stores T. /// If the async method returns Task or void, this field stores void. /// - public IType AsyncReturnType; + public IType? AsyncReturnType; /// /// If this function is an iterator/async, this field stores the compiler-generated MoveNext() method. /// - public IMethod MoveNextMethod; + public IMethod? MoveNextMethod; /// /// If this function is a local function, this field stores the reduced version of the function. /// - internal TypeSystem.Implementation.LocalFunctionMethod ReducedMethod; + internal TypeSystem.Implementation.LocalFunctionMethod? ReducedMethod; public DebugInfo.AsyncDebugInfo AsyncDebugInfo; @@ -131,8 +131,10 @@ namespace ICSharpCode.Decompiler.IL get { if (ctorCallStart == int.MinValue) { - if (!this.Method.IsConstructor || this.Method.IsStatic) + if (this.Method == null || !this.Method.IsConstructor || this.Method.IsStatic) + { ctorCallStart = -1; + } else { ctorCallStart = this.Descendants.FirstOrDefault(d => d is CallInstruction call && !(call is NewObj) @@ -150,7 +152,7 @@ namespace ICSharpCode.Decompiler.IL /// T is the delegate type that matches the signature of this method. /// Otherwise this must be null. /// - public IType DelegateType; + public IType? DelegateType; ILFunctionKind kind; @@ -181,7 +183,7 @@ namespace ICSharpCode.Decompiler.IL /// where the stack is empty, nop instructions, and the instruction following /// a call instruction /// - public List SequencePointCandidates { get; set; } + public List? SequencePointCandidates { get; set; } /// /// Constructs a new ILFunction from the given metadata and with the given ILAst body. @@ -408,18 +410,18 @@ namespace ICSharpCode.Decompiler.IL int helperVariableCount; - public ILVariable RegisterVariable(VariableKind kind, IType type, string name = null) + public ILVariable RegisterVariable(VariableKind kind, IType type, string? name = null) { return RegisterVariable(kind, type, type.GetStackType(), name); } - public ILVariable RegisterVariable(VariableKind kind, StackType stackType, string name = null) + public ILVariable RegisterVariable(VariableKind kind, StackType stackType, string? name = null) { var type = Method.Compilation.FindType(stackType.ToKnownTypeCode()); return RegisterVariable(kind, type, stackType, name); } - ILVariable RegisterVariable(VariableKind kind, IType type, StackType stackType, string name = null) + ILVariable RegisterVariable(VariableKind kind, IType type, StackType stackType, string? name = null) { var variable = new ILVariable(kind, type, stackType); if (string.IsNullOrWhiteSpace(name)) diff --git a/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs index 050924c9e..1c03facdd 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs @@ -60,7 +60,7 @@ namespace ICSharpCode.Decompiler.IL this.OpCode = opCode; } - protected void ValidateChild(ILInstruction inst) + protected void ValidateChild(ILInstruction? inst) { if (inst == null) throw new ArgumentNullException(nameof(inst)); diff --git a/ICSharpCode.Decompiler/IL/Instructions/ILVariableCollection.cs b/ICSharpCode.Decompiler/IL/Instructions/ILVariableCollection.cs index a47dbd622..16d3754ed 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ILVariableCollection.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/ILVariableCollection.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2016 Daniel Grunwald +#nullable enable +// Copyright (c) 2016 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -128,7 +129,7 @@ namespace ICSharpCode.Decompiler.IL { // However, remove unused this-parameters of delegates, expression trees, etc. // These will be replaced with the top-level function's this-parameter. - if (v.Index == -1 && v.Function.Kind != ILFunctionKind.TopLevelFunction) + if (v.Index == -1 && v.Function!.Kind != ILFunctionKind.TopLevelFunction) return true; return false; } diff --git a/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs index 1d668423b..5f367703e 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -35,7 +36,7 @@ namespace ICSharpCode.Decompiler.IL /// partial class IfInstruction : ILInstruction { - public IfInstruction(ILInstruction condition, ILInstruction trueInst, ILInstruction falseInst = null) : base(OpCode.IfInstruction) + public IfInstruction(ILInstruction condition, ILInstruction trueInst, ILInstruction? falseInst = null) : base(OpCode.IfInstruction) { this.Condition = condition; this.TrueInst = trueInst; @@ -47,7 +48,7 @@ namespace ICSharpCode.Decompiler.IL return new IfInstruction(lhs, rhs, new LdcI4(0)); } - public static IfInstruction LogicOr(ILInstruction lhs, ILInstruction rhs) + public static IfInstruction LogicOr(ILInstruction lhs, ILInstruction? rhs) { return new IfInstruction(lhs, new LdcI4(1), rhs); } @@ -126,7 +127,7 @@ namespace ICSharpCode.Decompiler.IL if (slot == IfInstruction.ConditionSlot) return true; if (slot == IfInstruction.TrueInstSlot || slot == IfInstruction.FalseInstSlot || slot == NullCoalescingInstruction.FallbackInstSlot) - return IsInConditionSlot(inst.Parent); + return IsInConditionSlot(inst.Parent!); if (inst.Parent is Comp comp) { if (comp.Left == inst && comp.Right.MatchLdcI4(0)) diff --git a/ICSharpCode.Decompiler/IL/Instructions/LdFlda.cs b/ICSharpCode.Decompiler/IL/Instructions/LdFlda.cs index ecfaa3744..ff35a007c 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/LdFlda.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/LdFlda.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software diff --git a/ICSharpCode.Decompiler/IL/Instructions/LdLen.cs b/ICSharpCode.Decompiler/IL/Instructions/LdLen.cs index e36781759..dbb172100 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/LdLen.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/LdLen.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software diff --git a/ICSharpCode.Decompiler/IL/Instructions/Leave.cs b/ICSharpCode.Decompiler/IL/Instructions/Leave.cs index 5f76b8a58..94c42473d 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Leave.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Leave.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -32,9 +33,9 @@ namespace ICSharpCode.Decompiler.IL /// partial class Leave : ILInstruction, IBranchOrLeaveInstruction { - BlockContainer targetContainer; + BlockContainer? targetContainer; - public Leave(BlockContainer targetContainer, ILInstruction value = null) : base(OpCode.Leave) + public Leave(BlockContainer? targetContainer, ILInstruction? value = null) : base(OpCode.Leave) { // Note: ILReader will create Leave instructions with targetContainer==null to represent 'endfinally', // the targetContainer will then be filled in by BlockBuilder @@ -54,7 +55,7 @@ namespace ICSharpCode.Decompiler.IL } public BlockContainer TargetContainer { - get { return targetContainer; } + get { return targetContainer!; } set { if (targetContainer != null && IsConnected) targetContainer.LeaveCount--; @@ -109,8 +110,8 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(phase <= ILPhase.InILReader || this.IsDescendantOf(targetContainer)); - Debug.Assert(phase <= ILPhase.InILReader || phase == ILPhase.InAsyncAwait || value.ResultType == targetContainer.ResultType); + Debug.Assert(phase <= ILPhase.InILReader || this.IsDescendantOf(targetContainer!)); + Debug.Assert(phase <= ILPhase.InILReader || phase == ILPhase.InAsyncAwait || value.ResultType == targetContainer!.ResultType); } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) diff --git a/ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs index e30ec162b..5ec7437a5 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2017 Siegfried Pammer +#nullable enable +// Copyright (c) 2017 Siegfried Pammer // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software diff --git a/ICSharpCode.Decompiler/IL/Instructions/LogicInstructions.cs b/ICSharpCode.Decompiler/IL/Instructions/LogicInstructions.cs index b62c67216..25394fc9b 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/LogicInstructions.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/LogicInstructions.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2017 Daniel Grunwald +#nullable enable +// Copyright (c) 2017 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software diff --git a/ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs index 091ebb72f..6280849f8 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2020 Siegfried Pammer +#nullable enable +// Copyright (c) 2020 Siegfried Pammer // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -18,10 +19,9 @@ using System; using System.Diagnostics; -using System.Linq; +using System.Diagnostics.CodeAnalysis; using ICSharpCode.Decompiler.TypeSystem; - namespace ICSharpCode.Decompiler.IL { partial class MatchInstruction : ILInstruction @@ -104,7 +104,7 @@ namespace ICSharpCode.Decompiler.IL } } - public MatchInstruction(ILVariable variable, ILInstruction testedOperand) + public MatchInstruction(ILVariable variable, ILInstruction? testedOperand) : this(variable, method: null, testedOperand) { } @@ -118,7 +118,7 @@ namespace ICSharpCode.Decompiler.IL /// (even if the pattern fails to match!). /// The pattern matching instruction evaluates to 1 (as I4) if the pattern matches, or 0 otherwise. /// - public static bool IsPatternMatch(ILInstruction inst, out ILInstruction testedOperand) + public static bool IsPatternMatch(ILInstruction? inst, [NotNullWhen(true)] out ILInstruction? testedOperand) { switch (inst) { @@ -185,8 +185,8 @@ namespace ICSharpCode.Decompiler.IL Debug.Assert(SubPatterns.Count >= NumPositionalPatterns); foreach (var subPattern in SubPatterns) { - if (!IsPatternMatch(subPattern, out ILInstruction operand)) - Debug.Fail("Sub-Pattern must be a valid pattern"); + if (!IsPatternMatch(subPattern, out ILInstruction? operand)) + throw new InvalidOperationException("Sub-Pattern must be a valid pattern"); // the first child is TestedOperand int subPatternIndex = subPattern.ChildIndex - 1; if (subPatternIndex < NumPositionalPatterns) diff --git a/ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs b/ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs index a10d96d59..bbb09376e 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software diff --git a/ICSharpCode.Decompiler/IL/Instructions/NullCoalescingInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/NullCoalescingInstruction.cs index 7f3e07816..f02fa6741 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/NullCoalescingInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/NullCoalescingInstruction.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2017 Siegfried Pammer +#nullable enable +// Copyright (c) 2017 Siegfried Pammer // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software diff --git a/ICSharpCode.Decompiler/IL/Instructions/NullableInstructions.cs b/ICSharpCode.Decompiler/IL/Instructions/NullableInstructions.cs index 05fffc1bc..6f6011fe0 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/NullableInstructions.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/NullableInstructions.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2018 Daniel Grunwald +#nullable enable +// Copyright (c) 2018 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software diff --git a/ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs b/ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs index 5c245dcdc..aa42395b4 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -16,8 +17,9 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -using ICSharpCode.Decompiler.TypeSystem; +using System.Diagnostics.CodeAnalysis; +using ICSharpCode.Decompiler.TypeSystem; namespace ICSharpCode.Decompiler.IL { partial class ILInstruction @@ -73,13 +75,13 @@ namespace ICSharpCode.Decompiler.IL return MatchLdcI(out long v) && v == val; } - public bool MatchLdLoc(ILVariable variable) + public bool MatchLdLoc(ILVariable? variable) { var inst = this as LdLoc; return inst != null && inst.Variable == variable; } - public bool MatchLdLoca(ILVariable variable) + public bool MatchLdLoca(ILVariable? variable) { var inst = this as LdLoca; return inst != null && inst.Variable == variable; @@ -88,7 +90,7 @@ namespace ICSharpCode.Decompiler.IL /// /// Matches either ldloc (if the variable is a reference type), or ldloca (otherwise). /// - public bool MatchLdLocRef(ILVariable variable) + public bool MatchLdLocRef(ILVariable? variable) { return MatchLdLocRef(out var v) && v == variable; } @@ -96,7 +98,7 @@ namespace ICSharpCode.Decompiler.IL /// /// Matches either ldloc (if the variable is a reference type), or ldloca (otherwise). /// - public bool MatchLdLocRef(out ILVariable variable) + public bool MatchLdLocRef([NotNullWhen(true)] out ILVariable? variable) { switch (this) { @@ -118,7 +120,7 @@ namespace ICSharpCode.Decompiler.IL return inst != null && inst.Variable.Kind == VariableKind.Parameter && inst.Variable.Index < 0; } - public bool MatchStLoc(out ILVariable variable) + public bool MatchStLoc([NotNullWhen(true)] out ILVariable? variable) { var inst = this as StLoc; if (inst != null) @@ -130,7 +132,7 @@ namespace ICSharpCode.Decompiler.IL return false; } - public bool MatchStLoc(ILVariable variable, out ILInstruction value) + public bool MatchStLoc(ILVariable? variable, [NotNullWhen(true)] out ILInstruction? value) { var inst = this as StLoc; if (inst != null && inst.Variable == variable) @@ -142,7 +144,7 @@ namespace ICSharpCode.Decompiler.IL return false; } - public bool MatchLdLen(StackType type, out ILInstruction array) + public bool MatchLdLen(StackType type, [NotNullWhen(true)] out ILInstruction? array) { var inst = this as LdLen; if (inst != null && inst.ResultType == type) @@ -154,7 +156,7 @@ namespace ICSharpCode.Decompiler.IL return false; } - public bool MatchReturn(out ILInstruction value) + public bool MatchReturn([NotNullWhen(true)] out ILInstruction? value) { var inst = this as Leave; if (inst != null && inst.IsLeavingFunction) @@ -166,7 +168,7 @@ namespace ICSharpCode.Decompiler.IL return false; } - public bool MatchBranch(out Block targetBlock) + public bool MatchBranch([NotNullWhen(true)] out Block? targetBlock) { var inst = this as Branch; if (inst != null) @@ -178,13 +180,13 @@ namespace ICSharpCode.Decompiler.IL return false; } - public bool MatchBranch(Block targetBlock) + public bool MatchBranch(Block? targetBlock) { var inst = this as Branch; return inst != null && inst.TargetBlock == targetBlock; } - public bool MatchLeave(out BlockContainer targetContainer, out ILInstruction value) + public bool MatchLeave([NotNullWhen(true)] out BlockContainer? targetContainer, [NotNullWhen(true)] out ILInstruction? value) { var inst = this as Leave; if (inst != null) @@ -198,7 +200,7 @@ namespace ICSharpCode.Decompiler.IL return false; } - public bool MatchLeave(BlockContainer targetContainer, out ILInstruction value) + public bool MatchLeave(BlockContainer? targetContainer, [NotNullWhen(true)] out ILInstruction? value) { var inst = this as Leave; if (inst != null && targetContainer == inst.TargetContainer) @@ -210,7 +212,7 @@ namespace ICSharpCode.Decompiler.IL return false; } - public bool MatchLeave(out BlockContainer targetContainer) + public bool MatchLeave([NotNullWhen(true)] out BlockContainer? targetContainer) { var inst = this as Leave; if (inst != null && inst.Value.MatchNop()) @@ -222,16 +224,15 @@ namespace ICSharpCode.Decompiler.IL return false; } - public bool MatchLeave(BlockContainer targetContainer) + public bool MatchLeave(BlockContainer? targetContainer) { var inst = this as Leave; return inst != null && inst.TargetContainer == targetContainer && inst.Value.MatchNop(); } - public bool MatchIfInstruction(out ILInstruction condition, out ILInstruction trueInst, out ILInstruction falseInst) + public bool MatchIfInstruction([NotNullWhen(true)] out ILInstruction? condition, [NotNullWhen(true)] out ILInstruction? trueInst, [NotNullWhen(true)] out ILInstruction? falseInst) { - var inst = this as IfInstruction; - if (inst != null) + if (this is IfInstruction inst) { condition = inst.Condition; trueInst = inst.TrueInst; @@ -244,7 +245,7 @@ namespace ICSharpCode.Decompiler.IL return false; } - public bool MatchIfInstructionPositiveCondition(out ILInstruction condition, out ILInstruction trueInst, out ILInstruction falseInst) + public bool MatchIfInstructionPositiveCondition([NotNullWhen(true)] out ILInstruction? condition, [NotNullWhen(true)] out ILInstruction? trueInst, [NotNullWhen(true)] out ILInstruction? falseInst) { if (MatchIfInstruction(out condition, out trueInst, out falseInst)) { @@ -252,7 +253,7 @@ namespace ICSharpCode.Decompiler.IL while (condition.MatchLogicNot(out var arg)) { condition = arg; - ILInstruction tmp = trueInst; + ILInstruction? tmp = trueInst; trueInst = falseInst; falseInst = tmp; } @@ -264,7 +265,7 @@ namespace ICSharpCode.Decompiler.IL /// /// Matches an if instruction where the false instruction is a nop. /// - public bool MatchIfInstruction(out ILInstruction condition, out ILInstruction trueInst) + public bool MatchIfInstruction([NotNullWhen(true)] out ILInstruction? condition, [NotNullWhen(true)] out ILInstruction? trueInst) { var inst = this as IfInstruction; if (inst != null && inst.FalseInst.MatchNop()) @@ -283,7 +284,7 @@ namespace ICSharpCode.Decompiler.IL /// Note: unlike C# '&&', this instruction is not limited to booleans, /// but allows passing through arbitrary I4 values on the rhs (but not on the lhs). /// - public bool MatchLogicAnd(out ILInstruction lhs, out ILInstruction rhs) + public bool MatchLogicAnd([NotNullWhen(true)] out ILInstruction? lhs, [NotNullWhen(true)] out ILInstruction? rhs) { var inst = this as IfInstruction; if (inst != null && inst.FalseInst.MatchLdcI4(0)) @@ -302,7 +303,7 @@ namespace ICSharpCode.Decompiler.IL /// Note: unlike C# '||', this instruction is not limited to booleans, /// but allows passing through arbitrary I4 values on the rhs (but not on the lhs). /// - public bool MatchLogicOr(out ILInstruction lhs, out ILInstruction rhs) + public bool MatchLogicOr([NotNullWhen(true)] out ILInstruction? lhs, [NotNullWhen(true)] out ILInstruction? rhs) { var inst = this as IfInstruction; if (inst != null && inst.TrueInst.MatchLdcI4(1)) @@ -319,7 +320,7 @@ namespace ICSharpCode.Decompiler.IL /// /// Matches an logical negation. /// - public bool MatchLogicNot(out ILInstruction arg) + public bool MatchLogicNot([NotNullWhen(true)] out ILInstruction? arg) { if (this is Comp comp && comp.Kind == ComparisonKind.Equality && comp.LiftingKind == ComparisonLiftingKind.None @@ -332,7 +333,7 @@ namespace ICSharpCode.Decompiler.IL return false; } - public bool MatchTryCatchHandler(out ILVariable variable) + public bool MatchTryCatchHandler([NotNullWhen(true)] out ILVariable? variable) { var inst = this as TryCatchHandler; if (inst != null) @@ -347,7 +348,7 @@ namespace ICSharpCode.Decompiler.IL /// /// Matches comp(left == right) or logic.not(comp(left != right)). /// - public bool MatchCompEquals(out ILInstruction left, out ILInstruction right) + public bool MatchCompEquals([NotNullWhen(true)] out ILInstruction? left, [NotNullWhen(true)] out ILInstruction? right) { ILInstruction thisInst = this; var compKind = ComparisonKind.Equality; @@ -376,7 +377,7 @@ namespace ICSharpCode.Decompiler.IL /// /// Matches 'comp(arg == ldnull)' /// - public bool MatchCompEqualsNull(out ILInstruction arg) + public bool MatchCompEqualsNull([NotNullWhen(true)] out ILInstruction? arg) { if (!MatchCompEquals(out var left, out var right)) { @@ -403,7 +404,7 @@ namespace ICSharpCode.Decompiler.IL /// /// Matches 'comp(arg != ldnull)' /// - public bool MatchCompNotEqualsNull(out ILInstruction arg) + public bool MatchCompNotEqualsNull([NotNullWhen(true)] out ILInstruction? arg) { if (!MatchCompNotEquals(out var left, out var right)) { @@ -430,7 +431,7 @@ namespace ICSharpCode.Decompiler.IL /// /// Matches comp(left != right) or logic.not(comp(left == right)). /// - public bool MatchCompNotEquals(out ILInstruction left, out ILInstruction right) + public bool MatchCompNotEquals([NotNullWhen(true)] out ILInstruction? left, [NotNullWhen(true)] out ILInstruction? right) { ILInstruction thisInst = this; var compKind = ComparisonKind.Inequality; @@ -456,7 +457,7 @@ namespace ICSharpCode.Decompiler.IL } } - public bool MatchLdFld(out ILInstruction target, out IField field) + public bool MatchLdFld([NotNullWhen(true)] out ILInstruction? target, [NotNullWhen(true)] out IField? field) { if (this is LdObj ldobj && ldobj.Target is LdFlda ldflda && ldobj.UnalignedPrefix == 0 && !ldobj.IsVolatile) { @@ -472,7 +473,7 @@ namespace ICSharpCode.Decompiler.IL return false; } - public bool MatchLdsFld(out IField field) + public bool MatchLdsFld([NotNullWhen(true)] out IField? field) { if (this is LdObj ldobj && ldobj.Target is LdsFlda ldsflda && ldobj.UnalignedPrefix == 0 && !ldobj.IsVolatile) { @@ -483,12 +484,12 @@ namespace ICSharpCode.Decompiler.IL return false; } - public bool MatchLdsFld(IField field) + public bool MatchLdsFld(IField? field) { return MatchLdsFld(out var f) && f.Equals(field); } - public bool MatchStsFld(out IField field, out ILInstruction value) + public bool MatchStsFld([NotNullWhen(true)] out IField? field, [NotNullWhen(true)] out ILInstruction? value) { if (this is StObj stobj && stobj.Target is LdsFlda ldsflda && stobj.UnalignedPrefix == 0 && !stobj.IsVolatile) { @@ -501,7 +502,7 @@ namespace ICSharpCode.Decompiler.IL return false; } - public bool MatchStFld(out ILInstruction target, out IField field, out ILInstruction value) + public bool MatchStFld([NotNullWhen(true)] out ILInstruction? target, [NotNullWhen(true)] out IField? field, [NotNullWhen(true)] out ILInstruction? value) { if (this is StObj stobj && stobj.Target is LdFlda ldflda && stobj.UnalignedPrefix == 0 && !stobj.IsVolatile) { @@ -522,7 +523,7 @@ namespace ICSharpCode.Decompiler.IL return op != null && op.Operator == @operator; } - public bool MatchBinaryNumericInstruction(BinaryNumericOperator @operator, out ILInstruction left, out ILInstruction right) + public bool MatchBinaryNumericInstruction(BinaryNumericOperator @operator, [NotNullWhen(true)] out ILInstruction? left, [NotNullWhen(true)] out ILInstruction? right) { var op = this as BinaryNumericInstruction; if (op != null && op.Operator == @operator) @@ -536,7 +537,7 @@ namespace ICSharpCode.Decompiler.IL return false; } - public bool MatchBinaryNumericInstruction(out BinaryNumericOperator @operator, out ILInstruction left, out ILInstruction right) + public bool MatchBinaryNumericInstruction(out BinaryNumericOperator @operator, [NotNullWhen(true)] out ILInstruction? left, [NotNullWhen(true)] out ILInstruction? right) { var op = this as BinaryNumericInstruction; if (op != null) diff --git a/ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs index bcd30b628..a05f0d06e 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -40,7 +41,7 @@ namespace ICSharpCode.Decompiler.IL partial class Nop { - public string Comment; + public string? Comment; public NopKind Kind; @@ -61,10 +62,10 @@ namespace ICSharpCode.Decompiler.IL partial class InvalidBranch : SimpleInstruction { - public string Message; + public string? Message; public StackType ExpectedResultType = StackType.Void; - public InvalidBranch(string message) : this() + public InvalidBranch(string? message) : this() { this.Message = message; } @@ -88,10 +89,10 @@ namespace ICSharpCode.Decompiler.IL partial class InvalidExpression : SimpleInstruction { - public string Message; + public string? Message; public StackType ExpectedResultType = StackType.Unknown; - public InvalidExpression(string message) : this() + public InvalidExpression(string? message) : this() { this.Message = message; } diff --git a/ICSharpCode.Decompiler/IL/Instructions/StLoc.cs b/ICSharpCode.Decompiler/IL/Instructions/StLoc.cs index f8a0c8914..e036f0cdf 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/StLoc.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/StLoc.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -38,8 +39,8 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function)); - Debug.Assert(phase <= ILPhase.InILReader || variable.Function.Variables[variable.IndexInFunction] == variable); + Debug.Assert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function!)); + Debug.Assert(phase <= ILPhase.InILReader || variable.Function!.Variables[variable.IndexInFunction] == variable); Debug.Assert(value.ResultType == variable.StackType); } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs b/ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs index 9b3044eae..f8e041fcf 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2017 Siegfried Pammer +#nullable enable +// Copyright (c) 2017 Siegfried Pammer // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -23,23 +24,23 @@ namespace ICSharpCode.Decompiler.IL { partial class StringToInt { - public List<(string Key, int Value)> Map { get; } + public List<(string? Key, int Value)> Map { get; } - public StringToInt(ILInstruction argument, List<(string Key, int Value)> map) + public StringToInt(ILInstruction? argument, List<(string? Key, int Value)> map) : base(OpCode.StringToInt) { this.Argument = argument; this.Map = map; } - public StringToInt(ILInstruction argument, string[] map) + public StringToInt(ILInstruction? argument, string?[] map) : this(argument, ArrayToDictionary(map)) { } - static List<(string Key, int Value)> ArrayToDictionary(string[] map) + static List<(string? Key, int Value)> ArrayToDictionary(string?[] map) { - var dict = new List<(string Key, int Value)>(); + var dict = new List<(string? Key, int Value)>(); for (int i = 0; i < map.Length; i++) { dict.Add((map[i], i)); diff --git a/ICSharpCode.Decompiler/IL/Instructions/SwitchInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/SwitchInstruction.cs index 816de88e8..aa3a55a56 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/SwitchInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/SwitchInstruction.cs @@ -1,3 +1,4 @@ +#nullable enable // Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team // // Permission is hereby granted, free of charge, to any person obtaining a copy of this @@ -16,7 +17,6 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -using System; using System.Diagnostics; using System.Linq; @@ -49,7 +49,7 @@ namespace ICSharpCode.Decompiler.IL this.Sections = new InstructionCollection(this, 1); } - ILInstruction value; + ILInstruction value = null!; public ILInstruction Value { get { return this.value; } set { diff --git a/ICSharpCode.Decompiler/IL/Instructions/TryInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/TryInstruction.cs index 228695ff1..fd35557dd 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/TryInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/TryInstruction.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -33,7 +34,7 @@ namespace ICSharpCode.Decompiler.IL this.TryBlock = tryBlock; } - ILInstruction tryBlock; + ILInstruction tryBlock = null!; public ILInstruction TryBlock { get { return this.tryBlock; } set { @@ -144,7 +145,7 @@ namespace ICSharpCode.Decompiler.IL base.CheckInvariant(phase); Debug.Assert(Parent is TryCatch); Debug.Assert(filter.ResultType == StackType.I4); - Debug.Assert(this.IsDescendantOf(variable.Function)); + Debug.Assert(this.IsDescendantOf(variable.Function!)); } public override StackType ResultType { @@ -202,7 +203,7 @@ namespace ICSharpCode.Decompiler.IL this.FinallyBlock = finallyBlock; } - ILInstruction finallyBlock; + ILInstruction finallyBlock = null!; public ILInstruction FinallyBlock { get { return this.finallyBlock; } set { @@ -299,7 +300,7 @@ namespace ICSharpCode.Decompiler.IL this.FaultBlock = faultBlock; } - ILInstruction faultBlock; + ILInstruction faultBlock = null!; public ILInstruction FaultBlock { get { return this.faultBlock; } set { diff --git a/ICSharpCode.Decompiler/IL/Instructions/UnaryInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/UnaryInstruction.cs index de0a7e02b..cb989fcab 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/UnaryInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/UnaryInstruction.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software diff --git a/ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs index b7a678ad4..2b642f615 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2017 Siegfried Pammer +#nullable enable +// Copyright (c) 2017 Siegfried Pammer // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software diff --git a/ICSharpCode.Decompiler/IL/Patterns/AnyNode.cs b/ICSharpCode.Decompiler/IL/Patterns/AnyNode.cs index 9f4f507ba..52e5c0f05 100644 --- a/ICSharpCode.Decompiler/IL/Patterns/AnyNode.cs +++ b/ICSharpCode.Decompiler/IL/Patterns/AnyNode.cs @@ -1,8 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +#nullable enable +using System; namespace ICSharpCode.Decompiler.IL.Patterns { @@ -37,19 +34,20 @@ namespace ICSharpCode.Decompiler.IL.Patterns partial class AnyNode : PatternInstruction { - CaptureGroup group; + CaptureGroup? group; - public AnyNode(CaptureGroup group = null) + public AnyNode(CaptureGroup? group = null) : base(OpCode.AnyNode) { this.group = group; } - protected internal override bool PerformMatch(ILInstruction other, ref Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Match match) { if (other == null) return false; - match.Add(group, other); + if (group != null) + match.Add(group, other); return true; } } diff --git a/ICSharpCode.Decompiler/IL/Patterns/ListMatch.cs b/ICSharpCode.Decompiler/IL/Patterns/ListMatch.cs index 426e2a8d9..d1088a2e6 100644 --- a/ICSharpCode.Decompiler/IL/Patterns/ListMatch.cs +++ b/ICSharpCode.Decompiler/IL/Patterns/ListMatch.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2016 Daniel Grunwald +#nullable enable +// Copyright (c) 2016 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -44,7 +45,7 @@ namespace ICSharpCode.Decompiler.IL.Patterns /// If the method returns true, it adds the capture groups (if any) to the match. /// If the method returns false, the match object remains in a partially-updated state and needs to be restored /// before it can be reused. - internal static bool DoMatch(IReadOnlyList patterns, IReadOnlyList syntaxList, ref Match match) + internal static bool DoMatch(IReadOnlyList patterns, IReadOnlyList syntaxList, ref Match match) { ListMatch listMatch = new ListMatch(syntaxList); do @@ -107,14 +108,14 @@ namespace ICSharpCode.Decompiler.IL.Patterns /// /// The syntax list we are matching against. /// - internal readonly IReadOnlyList SyntaxList; + internal readonly IReadOnlyList SyntaxList; /// /// The current index in the syntax list. /// internal int SyntaxIndex; - ListMatch(IReadOnlyList syntaxList) + ListMatch(IReadOnlyList syntaxList) { this.SyntaxList = syntaxList; this.SyntaxIndex = 0; @@ -122,8 +123,8 @@ namespace ICSharpCode.Decompiler.IL.Patterns this.restoreStack = null; } - List backtrackingStack; - Stack restoreStack; + List? backtrackingStack; + Stack? restoreStack; void AddSavePoint(SavePoint savepoint) { diff --git a/ICSharpCode.Decompiler/IL/Patterns/Match.cs b/ICSharpCode.Decompiler/IL/Patterns/Match.cs index 0cad96243..59fe705a6 100644 --- a/ICSharpCode.Decompiler/IL/Patterns/Match.cs +++ b/ICSharpCode.Decompiler/IL/Patterns/Match.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2016 Daniel Grunwald +#nullable enable +// Copyright (c) 2016 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -33,7 +34,7 @@ namespace ICSharpCode.Decompiler.IL.Patterns { static readonly List> emptyResults = new List>(); - List> results; + List>? results; /// /// Gets whether the match was successful. diff --git a/ICSharpCode.Decompiler/IL/PrimitiveType.cs b/ICSharpCode.Decompiler/IL/PrimitiveType.cs index 9d45d541d..95207ccb7 100644 --- a/ICSharpCode.Decompiler/IL/PrimitiveType.cs +++ b/ICSharpCode.Decompiler/IL/PrimitiveType.cs @@ -1,4 +1,5 @@ -// Copyright (c) 2014 Daniel Grunwald +#nullable enable +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software diff --git a/ICSharpCode.Decompiler/IL/SemanticHelper.cs b/ICSharpCode.Decompiler/IL/SemanticHelper.cs index 8a071b80f..d57d47c67 100644 --- a/ICSharpCode.Decompiler/IL/SemanticHelper.cs +++ b/ICSharpCode.Decompiler/IL/SemanticHelper.cs @@ -16,6 +16,8 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#nullable enable + using System.Linq; using ICSharpCode.Decompiler.Util; @@ -89,4 +91,4 @@ namespace ICSharpCode.Decompiler.IL return false; } } -} \ No newline at end of file +} diff --git a/ICSharpCode.Decompiler/IL/SlotInfo.cs b/ICSharpCode.Decompiler/IL/SlotInfo.cs index ec96ed0a3..765d7469f 100644 --- a/ICSharpCode.Decompiler/IL/SlotInfo.cs +++ b/ICSharpCode.Decompiler/IL/SlotInfo.cs @@ -16,6 +16,7 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#nullable enable namespace ICSharpCode.Decompiler.IL { diff --git a/ICSharpCode.Decompiler/IL/StackType.cs b/ICSharpCode.Decompiler/IL/StackType.cs index 6c303161f..f5f49e135 100644 --- a/ICSharpCode.Decompiler/IL/StackType.cs +++ b/ICSharpCode.Decompiler/IL/StackType.cs @@ -16,6 +16,7 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#nullable enable namespace ICSharpCode.Decompiler.IL { diff --git a/ICSharpCode.Decompiler/TypeSystem/IMember.cs b/ICSharpCode.Decompiler/TypeSystem/IMember.cs index d5f359072..999ee146a 100644 --- a/ICSharpCode.Decompiler/TypeSystem/IMember.cs +++ b/ICSharpCode.Decompiler/TypeSystem/IMember.cs @@ -62,6 +62,12 @@ namespace ICSharpCode.Decompiler.TypeSystem /// IType ReturnType { get; } + /// + /// Gets/Sets the declaring type (incl. type arguments, if any). + /// If this is not a specialized member, the value returned is equal to . + /// + new IType DeclaringType { get; } + /// /// Gets the interface members explicitly implemented by this member. /// diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/SyntheticRangeIndexer.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/SyntheticRangeIndexer.cs index 58e8ca0a0..85d6018e9 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/SyntheticRangeIndexer.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/SyntheticRangeIndexer.cs @@ -92,7 +92,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation TypeParameterSubstitution IMember.Substitution => underlyingMethod.Substitution; EntityHandle IEntity.MetadataToken => underlyingMethod.MetadataToken; public string Name => underlyingMethod.Name; - IType IEntity.DeclaringType => underlyingMethod.DeclaringType; + public IType DeclaringType => underlyingMethod.DeclaringType; ITypeDefinition IEntity.DeclaringTypeDefinition => underlyingMethod.DeclaringTypeDefinition; IModule IEntity.ParentModule => underlyingMethod.ParentModule; Accessibility IEntity.Accessibility => underlyingMethod.Accessibility; From 0414e7f8e91546e5a8e13190979c92d52072fab9 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 5 Jun 2021 16:32:24 +0200 Subject: [PATCH 3/6] Fix potential NRE in ILFunction.RegisterVariable() --- .../IL/Instructions/ILFunction.cs | 13 +------------ .../IL/Instructions/ILInstruction.cs | 5 +++-- .../IL/Transforms/FixLoneIsInst.cs | 3 +-- .../IL/Transforms/FixRemainingIncrements.cs | 3 +-- .../IL/Transforms/ILExtraction.cs | 17 ++++++++++++----- .../IL/Transforms/NamedArgumentTransform.cs | 8 +++----- .../IL/Transforms/TransformArrayInitializers.cs | 2 +- 7 files changed, 22 insertions(+), 29 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs b/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs index ca90cd4b0..306539276 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs @@ -412,18 +412,7 @@ namespace ICSharpCode.Decompiler.IL public ILVariable RegisterVariable(VariableKind kind, IType type, string? name = null) { - return RegisterVariable(kind, type, type.GetStackType(), name); - } - - public ILVariable RegisterVariable(VariableKind kind, StackType stackType, string? name = null) - { - var type = Method.Compilation.FindType(stackType.ToKnownTypeCode()); - return RegisterVariable(kind, type, stackType, name); - } - - ILVariable RegisterVariable(VariableKind kind, IType type, StackType stackType, string? name = null) - { - var variable = new ILVariable(kind, type, stackType); + var variable = new ILVariable(kind, type); if (string.IsNullOrWhiteSpace(name)) { name = "I_" + (helperVariableCount++); diff --git a/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs index 1c03facdd..4bb282025 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs @@ -24,6 +24,7 @@ using System.Diagnostics; using System.Threading; using ICSharpCode.Decompiler.IL.Patterns; +using ICSharpCode.Decompiler.IL.Transforms; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.Util; @@ -899,9 +900,9 @@ namespace ICSharpCode.Decompiler.IL /// If extraction is not possible, the ILAst is left unmodified and the function returns null. /// May return null if extraction is not possible. /// - public ILVariable Extract() + public ILVariable Extract(ILTransformContext context) { - return Transforms.ExtractionContext.Extract(this); + return Transforms.ExtractionContext.Extract(this, context); } /// diff --git a/ICSharpCode.Decompiler/IL/Transforms/FixLoneIsInst.cs b/ICSharpCode.Decompiler/IL/Transforms/FixLoneIsInst.cs index f70f3e972..50ddb43b0 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/FixLoneIsInst.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/FixLoneIsInst.cs @@ -16,7 +16,6 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -using System; using System.Collections.Generic; using System.Linq; @@ -63,7 +62,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms { // Use extraction to turn isInst.Argument into a pure instruction, thus making the emulation possible context.Step("FixLoneIsInst", isInst); - isInst.Argument.Extract(); + isInst.Argument.Extract(context); } } } diff --git a/ICSharpCode.Decompiler/IL/Transforms/FixRemainingIncrements.cs b/ICSharpCode.Decompiler/IL/Transforms/FixRemainingIncrements.cs index b79ff09c4..71bbbcad2 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/FixRemainingIncrements.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/FixRemainingIncrements.cs @@ -16,7 +16,6 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -73,7 +72,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms else { context.Step($"Fix {call.Method.Name} call at 0x{call.StartILOffset:x4} using new local", call); - var newVariable = call.Arguments[0].Extract(); + var newVariable = call.Arguments[0].Extract(context); if (newVariable == null) { Debug.Fail("Failed to extract argument of remaining increment/decrement"); diff --git a/ICSharpCode.Decompiler/IL/Transforms/ILExtraction.cs b/ICSharpCode.Decompiler/IL/Transforms/ILExtraction.cs index ba47d4738..5840dffe1 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/ILExtraction.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/ILExtraction.cs @@ -21,6 +21,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using ICSharpCode.Decompiler.TypeSystem; + namespace ICSharpCode.Decompiler.IL.Transforms { /// @@ -33,6 +35,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms /// readonly ILFunction Function; + readonly ILTransformContext context; + /// /// Combined flags of all instructions being moved. /// @@ -47,17 +51,19 @@ namespace ICSharpCode.Decompiler.IL.Transforms /// readonly List> MoveActions = new List>(); - ExtractionContext(ILFunction function) + ExtractionContext(ILFunction function, ILTransformContext context) { Debug.Assert(function != null); this.Function = function; + this.context = context; } internal void RegisterMove(ILInstruction predecessor) { FlagsBeingMoved |= predecessor.Flags; MoveActions.Add(delegate { - var v = Function.RegisterVariable(VariableKind.StackSlot, predecessor.ResultType); + var type = context.TypeSystem.FindType(predecessor.ResultType.ToKnownTypeCode()); + var v = Function.RegisterVariable(VariableKind.StackSlot, type); predecessor.ReplaceWith(new LdLoc(v)); return new StLoc(v, predecessor); }); @@ -91,10 +97,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms /// /// May return null if extraction is not possible. /// - public static ILVariable Extract(ILInstruction instToExtract) + public static ILVariable Extract(ILInstruction instToExtract, ILTransformContext context) { var function = instToExtract.Ancestors.OfType().First(); - ExtractionContext ctx = new ExtractionContext(function); + ExtractionContext ctx = new ExtractionContext(function, context); ctx.FlagsBeingMoved = instToExtract.Flags; ILInstruction inst = instToExtract; while (inst != null) @@ -113,8 +119,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms { // We've reached the target block, and extraction is possible all the way. int insertIndex = inst.ChildIndex; + var type = context.TypeSystem.FindType(instToExtract.ResultType.ToKnownTypeCode()); // Move instToExtract itself: - var v = function.RegisterVariable(VariableKind.StackSlot, instToExtract.ResultType); + var v = function.RegisterVariable(VariableKind.StackSlot, type); instToExtract.ReplaceWith(new LdLoc(v)); block.Instructions.Insert(insertIndex, new StLoc(v, instToExtract)); // Apply the other move actions: diff --git a/ICSharpCode.Decompiler/IL/Transforms/NamedArgumentTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/NamedArgumentTransform.cs index 5bad499c3..39bbfd425 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/NamedArgumentTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/NamedArgumentTransform.cs @@ -1,8 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; +using System.Diagnostics; using System.Linq; -using System.Text; using ICSharpCode.Decompiler.TypeSystem; @@ -90,7 +87,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms { var call = (CallInstruction)arg.Parent; Debug.Assert(context.Function == call.Ancestors.OfType().First()); - var v = context.Function.RegisterVariable(VariableKind.NamedArgument, arg.ResultType); + var type = context.TypeSystem.FindType(arg.ResultType.ToKnownTypeCode()); + var v = context.Function.RegisterVariable(VariableKind.NamedArgument, type); context.Step($"Introduce named argument '{v.Name}'", arg); if (!(call.Parent is Block namedArgBlock) || namedArgBlock.Kind != BlockKind.CallWithNamedArgs) { diff --git a/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs b/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs index 63b8a73b0..ed722b2cb 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs @@ -257,7 +257,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms var otherLoadOfV = v.LoadInstructions.FirstOrDefault(l => !(l.Parent is Cpblk)); if (otherLoadOfV == null) return false; - finalStore = otherLoadOfV.Parent.Extract(); + finalStore = otherLoadOfV.Parent.Extract(context); if (finalStore == null) return false; value = ((StLoc)finalStore.StoreInstructions[0]).Value; From bd29ed59819c2c920152b4e1651b4a76a47f6e4d Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 5 Jun 2021 16:43:03 +0200 Subject: [PATCH 4/6] Revert CSharpPrimitiveCast.cs: its used in Conversions.cs test case and thus must be compatible with old C# compiler versions --- ICSharpCode.Decompiler/Util/CSharpPrimitiveCast.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ICSharpCode.Decompiler/Util/CSharpPrimitiveCast.cs b/ICSharpCode.Decompiler/Util/CSharpPrimitiveCast.cs index cfc8c854c..b57516b45 100644 --- a/ICSharpCode.Decompiler/Util/CSharpPrimitiveCast.cs +++ b/ICSharpCode.Decompiler/Util/CSharpPrimitiveCast.cs @@ -16,10 +16,7 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -#nullable enable - using System; -using System.Diagnostics.CodeAnalysis; namespace ICSharpCode.Decompiler.Util { @@ -37,8 +34,7 @@ namespace ICSharpCode.Decompiler.Util /// /// Overflow checking is enabled and an overflow occurred. /// The cast is invalid, e.g. casting a boolean to an integer. - [return: NotNullIfNotNull("input")] - public static object? Cast(TypeCode targetType, object? input, bool checkForOverflow) + public static object Cast(TypeCode targetType, object input, bool checkForOverflow) { if (input == null) return null; From 245261a1e55214e318a2908a2d6c10b128ae92f2 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 5 Jun 2021 17:49:15 +0200 Subject: [PATCH 5/6] #nullable enable for Instructions.tt --- ICSharpCode.Decompiler/IL/Instructions.cs | 508 +++++++++--------- ICSharpCode.Decompiler/IL/Instructions.tt | 85 +-- .../IL/Instructions/Block.cs | 14 +- .../DeconstructResultInstruction.cs | 6 +- .../IL/Instructions/DynamicInstructions.cs | 2 +- .../IL/Instructions/ExpressionTreeCast.cs | 6 +- .../IL/Instructions/ILInstruction.cs | 15 +- .../IL/Instructions/MatchInstruction.cs | 20 +- .../IL/Instructions/StringToInt.cs | 4 +- ICSharpCode.Decompiler/Util/NullAttributes.cs | 8 + 10 files changed, 346 insertions(+), 322 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/Instructions.cs b/ICSharpCode.Decompiler/IL/Instructions.cs index 1cb69799f..ab6766660 100644 --- a/ICSharpCode.Decompiler/IL/Instructions.cs +++ b/ICSharpCode.Decompiler/IL/Instructions.cs @@ -16,9 +16,10 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#nullable enable + using System; -using System.Collections.Generic; -using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using ICSharpCode.Decompiler.TypeSystem; @@ -304,7 +305,7 @@ namespace ICSharpCode.Decompiler.IL this.Argument = argument; } public static readonly SlotInfo ArgumentSlot = new SlotInfo("Argument", canInlineInto: true); - ILInstruction argument; + ILInstruction argument = null!; public ILInstruction Argument { get { return this.argument; } set { @@ -383,7 +384,7 @@ namespace ICSharpCode.Decompiler.IL this.Right = right; } public static readonly SlotInfo LeftSlot = new SlotInfo("Left", canInlineInto: true); - ILInstruction left; + ILInstruction left = null!; public ILInstruction Left { get { return this.left; } set { @@ -392,7 +393,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo RightSlot = new SlotInfo("Right", canInlineInto: true); - ILInstruction right; + ILInstruction right = null!; public ILInstruction Right { get { return this.right; } set { @@ -475,11 +476,6 @@ namespace ICSharpCode.Decompiler.IL /// Instruction with a list of arguments. public abstract partial class CallInstruction : ILInstruction { - protected CallInstruction(OpCode opCode, params ILInstruction[] arguments) : base(opCode) - { - this.Arguments = new InstructionCollection(this, 0); - this.Arguments.AddRange(arguments); - } public static readonly SlotInfo ArgumentsSlot = new SlotInfo("Arguments", canInlineInto: true); public InstructionCollection Arguments { get; private set; } protected sealed override int GetChildCount() @@ -546,7 +542,7 @@ namespace ICSharpCode.Decompiler.IL public abstract partial class CompoundAssignmentInstruction : ILInstruction { public static readonly SlotInfo TargetSlot = new SlotInfo("Target", canInlineInto: true); - ILInstruction target; + ILInstruction target = null!; public ILInstruction Target { get { return this.target; } set { @@ -555,7 +551,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo ValueSlot = new SlotInfo("Value", canInlineInto: true); - ILInstruction value; + ILInstruction value = null!; public ILInstruction Value { get { return this.value; } set { @@ -683,7 +679,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitInvalidBranch(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as InvalidBranch; return o != null; @@ -720,7 +716,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitInvalidExpression(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as InvalidExpression; return o != null; @@ -748,7 +744,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitNop(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as Nop; return o != null; @@ -761,7 +757,7 @@ namespace ICSharpCode.Decompiler.IL public sealed partial class ILFunction : ILInstruction { public static readonly SlotInfo BodySlot = new SlotInfo("Body"); - ILInstruction body; + ILInstruction body = null!; public ILInstruction Body { get { return this.body; } set { @@ -829,7 +825,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitILFunction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as ILFunction; return o != null && this.body.PerformMatch(o.body, ref match) && Patterns.ListMatch.DoMatch(this.LocalFunctions, o.LocalFunctions, ref match); @@ -854,7 +850,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitBlockContainer(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as BlockContainer; return o != null && Patterns.ListMatch.DoMatch(this.Blocks, o.Blocks, ref match); @@ -879,7 +875,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitBlock(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as Block; return o != null && this.Kind == o.Kind && Patterns.ListMatch.DoMatch(this.Instructions, o.Instructions, ref match) && this.FinalInstruction.PerformMatch(o.FinalInstruction, ref match); @@ -893,8 +889,7 @@ namespace ICSharpCode.Decompiler.IL { public PinnedRegion(ILVariable variable, ILInstruction init, ILInstruction body) : base(OpCode.PinnedRegion) { - Debug.Assert(variable != null); - this.variable = variable; + this.variable = variable ?? throw new ArgumentNullException(nameof(variable)); this.Init = init; this.Body = body; } @@ -903,7 +898,7 @@ namespace ICSharpCode.Decompiler.IL public ILVariable Variable { get { return variable; } set { - Debug.Assert(value != null); + DebugAssert(value != null); if (IsConnected) variable.RemoveStoreInstruction(this); variable = value; @@ -932,7 +927,7 @@ namespace ICSharpCode.Decompiler.IL } public static readonly SlotInfo InitSlot = new SlotInfo("Init", canInlineInto: true); - ILInstruction init; + ILInstruction init = null!; public ILInstruction Init { get { return this.init; } set { @@ -941,7 +936,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo BodySlot = new SlotInfo("Body"); - ILInstruction body; + ILInstruction body = null!; public ILInstruction Body { get { return this.body; } set { @@ -1031,7 +1026,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitPinnedRegion(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as PinnedRegion; return o != null && variable == o.variable && this.init.PerformMatch(o.init, ref match) && this.body.PerformMatch(o.body, ref match); @@ -1039,9 +1034,9 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function)); - Debug.Assert(phase <= ILPhase.InILReader || variable.Function.Variables[variable.IndexInFunction] == variable); - Debug.Assert(Variable.Kind == VariableKind.PinnedRegionLocal); + DebugAssert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function!)); + DebugAssert(phase <= ILPhase.InILReader || variable.Function!.Variables[variable.IndexInFunction] == variable); + DebugAssert(Variable.Kind == VariableKind.PinnedRegionLocal); } } } @@ -1063,7 +1058,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitBinaryNumericInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as BinaryNumericInstruction; return o != null && this.Left.PerformMatch(o.Left, ref match) && this.Right.PerformMatch(o.Right, ref match) && CheckForOverflow == o.CheckForOverflow && Sign == o.Sign && Operator == o.Operator && IsLifted == o.IsLifted; @@ -1094,7 +1089,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitNumericCompoundAssign(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as NumericCompoundAssign; return o != null && type.Equals(o.type) && CheckForOverflow == o.CheckForOverflow && Sign == o.Sign && Operator == o.Operator && this.EvalMode == o.EvalMode && this.TargetKind == o.TargetKind && Target.PerformMatch(o.Target, ref match) && Value.PerformMatch(o.Value, ref match); @@ -1128,7 +1123,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitUserDefinedCompoundAssign(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as UserDefinedCompoundAssign; return o != null && this.Method.Equals(o.Method) && this.EvalMode == o.EvalMode && this.TargetKind == o.TargetKind && Target.PerformMatch(o.Target, ref match) && Value.PerformMatch(o.Value, ref match); @@ -1162,7 +1157,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDynamicCompoundAssign(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as DynamicCompoundAssign; return o != null && this.EvalMode == o.EvalMode && this.TargetKind == o.TargetKind && Target.PerformMatch(o.Target, ref match) && Value.PerformMatch(o.Value, ref match); @@ -1187,7 +1182,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitBitNot(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as BitNot; return o != null && this.Argument.PerformMatch(o.Argument, ref match) && IsLifted == o.IsLifted && UnderlyingResultType == o.UnderlyingResultType; @@ -1215,7 +1210,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitArglist(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as Arglist; return o != null; @@ -1249,7 +1244,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitBranch(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as Branch; return o != null && this.TargetBlock == o.TargetBlock; @@ -1262,7 +1257,7 @@ namespace ICSharpCode.Decompiler.IL public sealed partial class Leave : ILInstruction { public static readonly SlotInfo ValueSlot = new SlotInfo("Value", canInlineInto: true); - ILInstruction value; + ILInstruction value = null!; public ILInstruction Value { get { return this.value; } set { @@ -1324,7 +1319,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLeave(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as Leave; return o != null && this.value.PerformMatch(o.value, ref match) && this.TargetContainer == o.TargetContainer; @@ -1337,7 +1332,7 @@ namespace ICSharpCode.Decompiler.IL public sealed partial class IfInstruction : ILInstruction { public static readonly SlotInfo ConditionSlot = new SlotInfo("Condition", canInlineInto: true); - ILInstruction condition; + ILInstruction condition = null!; public ILInstruction Condition { get { return this.condition; } set { @@ -1346,7 +1341,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo TrueInstSlot = new SlotInfo("TrueInst"); - ILInstruction trueInst; + ILInstruction trueInst = null!; public ILInstruction TrueInst { get { return this.trueInst; } set { @@ -1355,7 +1350,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo FalseInstSlot = new SlotInfo("FalseInst"); - ILInstruction falseInst; + ILInstruction falseInst = null!; public ILInstruction FalseInst { get { return this.falseInst; } set { @@ -1432,7 +1427,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitIfInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as IfInstruction; return o != null && this.condition.PerformMatch(o.condition, ref match) && this.trueInst.PerformMatch(o.trueInst, ref match) && this.falseInst.PerformMatch(o.falseInst, ref match); @@ -1445,7 +1440,7 @@ namespace ICSharpCode.Decompiler.IL public sealed partial class NullCoalescingInstruction : ILInstruction { public static readonly SlotInfo ValueInstSlot = new SlotInfo("ValueInst", canInlineInto: true); - ILInstruction valueInst; + ILInstruction valueInst = null!; public ILInstruction ValueInst { get { return this.valueInst; } set { @@ -1454,7 +1449,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo FallbackInstSlot = new SlotInfo("FallbackInst"); - ILInstruction fallbackInst; + ILInstruction fallbackInst = null!; public ILInstruction FallbackInst { get { return this.fallbackInst; } set { @@ -1523,7 +1518,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitNullCoalescingInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as NullCoalescingInstruction; return o != null && this.valueInst.PerformMatch(o.valueInst, ref match) && this.fallbackInst.PerformMatch(o.fallbackInst, ref match); @@ -1548,7 +1543,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitSwitchInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as SwitchInstruction; return o != null && IsLifted == o.IsLifted && Value.PerformMatch(o.Value, ref match) && Patterns.ListMatch.DoMatch(this.Sections, o.Sections, ref match); @@ -1561,7 +1556,7 @@ namespace ICSharpCode.Decompiler.IL public sealed partial class SwitchSection : ILInstruction { public static readonly SlotInfo BodySlot = new SlotInfo("Body"); - ILInstruction body; + ILInstruction body = null!; public ILInstruction Body { get { return this.body; } set { @@ -1623,7 +1618,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitSwitchSection(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as SwitchSection; return o != null && this.body.PerformMatch(o.body, ref match) && this.Labels.SetEquals(o.Labels) && this.HasNullLabel == o.HasNullLabel; @@ -1648,7 +1643,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitTryCatch(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as TryCatch; return o != null && TryBlock.PerformMatch(o.TryBlock, ref match) && Patterns.ListMatch.DoMatch(Handlers, o.Handlers, ref match); @@ -1664,11 +1659,10 @@ namespace ICSharpCode.Decompiler.IL { this.Filter = filter; this.Body = body; - Debug.Assert(variable != null); - this.variable = variable; + this.variable = variable ?? throw new ArgumentNullException(nameof(variable)); } public static readonly SlotInfo FilterSlot = new SlotInfo("Filter"); - ILInstruction filter; + ILInstruction filter = null!; public ILInstruction Filter { get { return this.filter; } set { @@ -1677,7 +1671,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo BodySlot = new SlotInfo("Body"); - ILInstruction body; + ILInstruction body = null!; public ILInstruction Body { get { return this.body; } set { @@ -1738,7 +1732,7 @@ namespace ICSharpCode.Decompiler.IL public ILVariable Variable { get { return variable; } set { - Debug.Assert(value != null); + DebugAssert(value != null); if (IsConnected) variable.RemoveStoreInstruction(this); variable = value; @@ -1778,7 +1772,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitTryCatchHandler(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as TryCatchHandler; return o != null && this.filter.PerformMatch(o.filter, ref match) && this.body.PerformMatch(o.body, ref match) && variable == o.variable; @@ -1803,7 +1797,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitTryFinally(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as TryFinally; return o != null && TryBlock.PerformMatch(o.TryBlock, ref match) && finallyBlock.PerformMatch(o.finallyBlock, ref match); @@ -1828,7 +1822,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitTryFault(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as TryFault; return o != null && TryBlock.PerformMatch(o.TryBlock, ref match) && faultBlock.PerformMatch(o.faultBlock, ref match); @@ -1846,7 +1840,7 @@ namespace ICSharpCode.Decompiler.IL this.Body = body; } public static readonly SlotInfo OnExpressionSlot = new SlotInfo("OnExpression", canInlineInto: true); - ILInstruction onExpression; + ILInstruction onExpression = null!; public ILInstruction OnExpression { get { return this.onExpression; } set { @@ -1855,7 +1849,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo BodySlot = new SlotInfo("Body"); - ILInstruction body; + ILInstruction body = null!; public ILInstruction Body { get { return this.body; } set { @@ -1934,7 +1928,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLockInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LockInstruction; return o != null && this.onExpression.PerformMatch(o.onExpression, ref match) && this.body.PerformMatch(o.body, ref match); @@ -1942,7 +1936,7 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(onExpression.ResultType == StackType.O); + DebugAssert(onExpression.ResultType == StackType.O); } } } @@ -1953,8 +1947,7 @@ namespace ICSharpCode.Decompiler.IL { public UsingInstruction(ILVariable variable, ILInstruction resourceExpression, ILInstruction body) : base(OpCode.UsingInstruction) { - Debug.Assert(variable != null); - this.variable = variable; + this.variable = variable ?? throw new ArgumentNullException(nameof(variable)); this.ResourceExpression = resourceExpression; this.Body = body; } @@ -1962,7 +1955,7 @@ namespace ICSharpCode.Decompiler.IL public ILVariable Variable { get { return variable; } set { - Debug.Assert(value != null); + DebugAssert(value != null); if (IsConnected) variable.RemoveStoreInstruction(this); variable = value; @@ -1991,7 +1984,7 @@ namespace ICSharpCode.Decompiler.IL } public static readonly SlotInfo ResourceExpressionSlot = new SlotInfo("ResourceExpression", canInlineInto: true); - ILInstruction resourceExpression; + ILInstruction resourceExpression = null!; public ILInstruction ResourceExpression { get { return this.resourceExpression; } set { @@ -2000,7 +1993,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo BodySlot = new SlotInfo("Body"); - ILInstruction body; + ILInstruction body = null!; public ILInstruction Body { get { return this.body; } set { @@ -2079,7 +2072,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitUsingInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as UsingInstruction; return o != null && variable == o.variable && this.resourceExpression.PerformMatch(o.resourceExpression, ref match) && this.body.PerformMatch(o.body, ref match); @@ -2087,9 +2080,9 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function)); - Debug.Assert(phase <= ILPhase.InILReader || variable.Function.Variables[variable.IndexInFunction] == variable); - Debug.Assert(resourceExpression.ResultType == StackType.O); + DebugAssert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function!)); + DebugAssert(phase <= ILPhase.InILReader || variable.Function!.Variables[variable.IndexInFunction] == variable); + DebugAssert(resourceExpression.ResultType == StackType.O); } } } @@ -2123,7 +2116,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDebugBreak(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as DebugBreak; return o != null; @@ -2148,7 +2141,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitComp(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as Comp; return o != null && this.Left.PerformMatch(o.Left, ref match) && this.Right.PerformMatch(o.Right, ref match) && this.Kind == o.Kind && this.Sign == o.Sign && this.LiftingKind == o.LiftingKind; @@ -2219,7 +2212,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitCallIndirect(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as CallIndirect; return o != null && EqualSignature(o) && Patterns.ListMatch.DoMatch(this.Arguments, o.Arguments, ref match) && this.FunctionPointer.PerformMatch(o.FunctionPointer, ref match); @@ -2256,7 +2249,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitCkfinite(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as Ckfinite; return o != null && this.Argument.PerformMatch(o.Argument, ref match); @@ -2281,7 +2274,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitConv(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as Conv; return o != null && this.Argument.PerformMatch(o.Argument, ref match) && CheckForOverflow == o.CheckForOverflow && Kind == o.Kind && InputSign == o.InputSign && TargetType == o.TargetType && IsLifted == o.IsLifted; @@ -2295,14 +2288,13 @@ namespace ICSharpCode.Decompiler.IL { public LdLoc(ILVariable variable) : base(OpCode.LdLoc) { - Debug.Assert(variable != null); - this.variable = variable; + this.variable = variable ?? throw new ArgumentNullException(nameof(variable)); } ILVariable variable; public ILVariable Variable { get { return variable; } set { - Debug.Assert(value != null); + DebugAssert(value != null); if (IsConnected) variable.RemoveLoadInstruction(this); variable = value; @@ -2359,7 +2351,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdLoc(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdLoc; return o != null && variable == o.variable; @@ -2367,8 +2359,8 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function)); - Debug.Assert(phase <= ILPhase.InILReader || variable.Function.Variables[variable.IndexInFunction] == variable); + DebugAssert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function!)); + DebugAssert(phase <= ILPhase.InILReader || variable.Function!.Variables[variable.IndexInFunction] == variable); } } } @@ -2379,15 +2371,14 @@ namespace ICSharpCode.Decompiler.IL { public LdLoca(ILVariable variable) : base(OpCode.LdLoca) { - Debug.Assert(variable != null); - this.variable = variable; + this.variable = variable ?? throw new ArgumentNullException(nameof(variable)); } public override StackType ResultType { get { return StackType.Ref; } } ILVariable variable; public ILVariable Variable { get { return variable; } set { - Debug.Assert(value != null); + DebugAssert(value != null); if (IsConnected) variable.RemoveAddressInstruction(this); variable = value; @@ -2434,7 +2425,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdLoca(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdLoca; return o != null && variable == o.variable; @@ -2442,8 +2433,8 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function)); - Debug.Assert(phase <= ILPhase.InILReader || variable.Function.Variables[variable.IndexInFunction] == variable); + DebugAssert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function!)); + DebugAssert(phase <= ILPhase.InILReader || variable.Function!.Variables[variable.IndexInFunction] == variable); } } } @@ -2455,15 +2446,14 @@ namespace ICSharpCode.Decompiler.IL { public StLoc(ILVariable variable, ILInstruction value) : base(OpCode.StLoc) { - Debug.Assert(variable != null); - this.variable = variable; + this.variable = variable ?? throw new ArgumentNullException(nameof(variable)); this.Value = value; } ILVariable variable; public ILVariable Variable { get { return variable; } set { - Debug.Assert(value != null); + DebugAssert(value != null); if (IsConnected) variable.RemoveStoreInstruction(this); variable = value; @@ -2492,7 +2482,7 @@ namespace ICSharpCode.Decompiler.IL } public static readonly SlotInfo ValueSlot = new SlotInfo("Value", canInlineInto: true); - ILInstruction value; + ILInstruction value = null!; public ILInstruction Value { get { return this.value; } set { @@ -2573,7 +2563,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitStLoc(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as StLoc; return o != null && variable == o.variable && this.value.PerformMatch(o.value, ref match); @@ -2591,7 +2581,7 @@ namespace ICSharpCode.Decompiler.IL this.type = type; } public static readonly SlotInfo ValueSlot = new SlotInfo("Value", canInlineInto: true); - ILInstruction value; + ILInstruction value = null!; public ILInstruction Value { get { return this.value; } set { @@ -2678,7 +2668,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitAddressOf(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as AddressOf; return o != null && this.value.PerformMatch(o.value, ref match) && type.Equals(o.type); @@ -2706,7 +2696,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitThreeValuedBoolAnd(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as ThreeValuedBoolAnd; return o != null && this.Left.PerformMatch(o.Left, ref match) && this.Right.PerformMatch(o.Right, ref match); @@ -2734,7 +2724,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitThreeValuedBoolOr(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as ThreeValuedBoolOr; return o != null && this.Left.PerformMatch(o.Left, ref match) && this.Right.PerformMatch(o.Right, ref match); @@ -2774,7 +2764,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitNullableUnwrap(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as NullableUnwrap; return o != null && this.Argument.PerformMatch(o.Argument, ref match); @@ -2803,7 +2793,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitNullableRewrap(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as NullableRewrap; return o != null && this.Argument.PerformMatch(o.Argument, ref match); @@ -2840,7 +2830,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdStr(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdStr; return o != null && this.Value == o.Value; @@ -2877,7 +2867,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdcI4(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdcI4; return o != null && this.Value == o.Value; @@ -2914,7 +2904,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdcI8(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdcI8; return o != null && this.Value == o.Value; @@ -2951,7 +2941,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdcF4(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdcF4; return o != null && this.Value == o.Value; @@ -2988,7 +2978,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdcF8(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdcF8; return o != null && this.Value == o.Value; @@ -3025,7 +3015,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdcDecimal(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdcDecimal; return o != null && this.Value == o.Value; @@ -3053,7 +3043,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdNull(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdNull; return o != null; @@ -3071,7 +3061,7 @@ namespace ICSharpCode.Decompiler.IL } readonly IMethod method; /// Returns the method operand. - public IMethod Method { get { return method; } } + public IMethod Method => method; public override StackType ResultType { get { return StackType.I; } } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { @@ -3095,7 +3085,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdFtn(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdFtn; return o != null && object.Equals(method, o.method); @@ -3113,7 +3103,7 @@ namespace ICSharpCode.Decompiler.IL } readonly IMethod method; /// Returns the method operand. - public IMethod Method { get { return method; } } + public IMethod Method => method; public override StackType ResultType { get { return StackType.I; } } protected override InstructionFlags ComputeFlags() { @@ -3149,7 +3139,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdVirtFtn(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdVirtFtn; return o != null && this.Argument.PerformMatch(o.Argument, ref match) && object.Equals(method, o.method); @@ -3174,7 +3164,7 @@ namespace ICSharpCode.Decompiler.IL } readonly IMethod method; /// Returns the method operand. - public IMethod Method { get { return method; } } + public IMethod Method => method; public override StackType ResultType { get { return StackType.O; } } protected override InstructionFlags ComputeFlags() { @@ -3212,7 +3202,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdVirtDelegate(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdVirtDelegate; return o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type) && object.Equals(method, o.method); @@ -3254,7 +3244,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdTypeToken(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdTypeToken; return o != null && type.Equals(o.type); @@ -3293,7 +3283,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdMemberToken(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdMemberToken; return o != null && member.Equals(o.member); @@ -3330,7 +3320,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLocAlloc(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LocAlloc; return o != null && this.Argument.PerformMatch(o.Argument, ref match); @@ -3384,7 +3374,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLocAllocSpan(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LocAllocSpan; return o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type); @@ -3403,7 +3393,7 @@ namespace ICSharpCode.Decompiler.IL this.Size = size; } public static readonly SlotInfo DestAddressSlot = new SlotInfo("DestAddress", canInlineInto: true); - ILInstruction destAddress; + ILInstruction destAddress = null!; public ILInstruction DestAddress { get { return this.destAddress; } set { @@ -3412,7 +3402,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo SourceAddressSlot = new SlotInfo("SourceAddress", canInlineInto: true); - ILInstruction sourceAddress; + ILInstruction sourceAddress = null!; public ILInstruction SourceAddress { get { return this.sourceAddress; } set { @@ -3421,7 +3411,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo SizeSlot = new SlotInfo("Size", canInlineInto: true); - ILInstruction size; + ILInstruction size = null!; public ILInstruction Size { get { return this.size; } set { @@ -3528,7 +3518,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitCpblk(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as Cpblk; return o != null && this.destAddress.PerformMatch(o.destAddress, ref match) && this.sourceAddress.PerformMatch(o.sourceAddress, ref match) && this.size.PerformMatch(o.size, ref match) && IsVolatile == o.IsVolatile && UnalignedPrefix == o.UnalignedPrefix; @@ -3536,9 +3526,9 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(destAddress.ResultType == StackType.I || destAddress.ResultType == StackType.Ref); - Debug.Assert(sourceAddress.ResultType == StackType.I || sourceAddress.ResultType == StackType.Ref); - Debug.Assert(size.ResultType == StackType.I4); + DebugAssert(destAddress.ResultType == StackType.I || destAddress.ResultType == StackType.Ref); + DebugAssert(sourceAddress.ResultType == StackType.I || sourceAddress.ResultType == StackType.Ref); + DebugAssert(size.ResultType == StackType.I4); } } } @@ -3554,7 +3544,7 @@ namespace ICSharpCode.Decompiler.IL this.Size = size; } public static readonly SlotInfo AddressSlot = new SlotInfo("Address", canInlineInto: true); - ILInstruction address; + ILInstruction address = null!; public ILInstruction Address { get { return this.address; } set { @@ -3563,7 +3553,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo ValueSlot = new SlotInfo("Value", canInlineInto: true); - ILInstruction value; + ILInstruction value = null!; public ILInstruction Value { get { return this.value; } set { @@ -3572,7 +3562,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo SizeSlot = new SlotInfo("Size", canInlineInto: true); - ILInstruction size; + ILInstruction size = null!; public ILInstruction Size { get { return this.size; } set { @@ -3679,7 +3669,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitInitblk(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as Initblk; return o != null && this.address.PerformMatch(o.address, ref match) && this.value.PerformMatch(o.value, ref match) && this.size.PerformMatch(o.size, ref match) && IsVolatile == o.IsVolatile && UnalignedPrefix == o.UnalignedPrefix; @@ -3687,9 +3677,9 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(address.ResultType == StackType.I || address.ResultType == StackType.Ref); - Debug.Assert(value.ResultType == StackType.I4); - Debug.Assert(size.ResultType == StackType.I4); + DebugAssert(address.ResultType == StackType.I || address.ResultType == StackType.Ref); + DebugAssert(value.ResultType == StackType.I4); + DebugAssert(size.ResultType == StackType.I4); } } } @@ -3704,7 +3694,7 @@ namespace ICSharpCode.Decompiler.IL this.field = field; } public static readonly SlotInfo TargetSlot = new SlotInfo("Target", canInlineInto: true); - ILInstruction target; + ILInstruction target = null!; public ILInstruction Target { get { return this.target; } set { @@ -3791,7 +3781,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdFlda(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdFlda; return o != null && this.target.PerformMatch(o.target, ref match) && DelayExceptions == o.DelayExceptions && field.Equals(o.field); @@ -3830,7 +3820,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdsFlda(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdsFlda; return o != null && field.Equals(o.field); @@ -3884,7 +3874,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitCastClass(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as CastClass; return o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type); @@ -3929,7 +3919,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitIsInst(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as IsInst; return o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type); @@ -3947,7 +3937,7 @@ namespace ICSharpCode.Decompiler.IL this.type = type; } public static readonly SlotInfo TargetSlot = new SlotInfo("Target", canInlineInto: true); - ILInstruction target; + ILInstruction target = null!; public ILInstruction Target { get { return this.target; } set { @@ -4042,7 +4032,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdObj(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdObj; return o != null && this.target.PerformMatch(o.target, ref match) && type.Equals(o.type) && IsVolatile == o.IsVolatile && UnalignedPrefix == o.UnalignedPrefix; @@ -4050,7 +4040,7 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(target.ResultType == StackType.Ref || target.ResultType == StackType.I); + DebugAssert(target.ResultType == StackType.Ref || target.ResultType == StackType.I); } } } @@ -4067,7 +4057,7 @@ namespace ICSharpCode.Decompiler.IL this.type = type; } public static readonly SlotInfo TargetSlot = new SlotInfo("Target", canInlineInto: true); - ILInstruction target; + ILInstruction target = null!; public ILInstruction Target { get { return this.target; } set { @@ -4076,7 +4066,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo ValueSlot = new SlotInfo("Value", canInlineInto: true); - ILInstruction value; + ILInstruction value = null!; public ILInstruction Value { get { return this.value; } set { @@ -4181,7 +4171,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitStObj(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as StObj; return o != null && this.target.PerformMatch(o.target, ref match) && this.value.PerformMatch(o.value, ref match) && type.Equals(o.type) && IsVolatile == o.IsVolatile && UnalignedPrefix == o.UnalignedPrefix; @@ -4189,8 +4179,8 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(target.ResultType == StackType.Ref || target.ResultType == StackType.I); - Debug.Assert(value.ResultType == type.GetStackType()); + DebugAssert(target.ResultType == StackType.Ref || target.ResultType == StackType.I); + DebugAssert(value.ResultType == type.GetStackType()); CheckTargetSlot(); } } @@ -4242,7 +4232,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitBox(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as Box; return o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type); @@ -4296,7 +4286,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitUnbox(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as Unbox; return o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type); @@ -4350,7 +4340,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitUnboxAny(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as UnboxAny; return o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type); @@ -4475,7 +4465,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitNewArr(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as NewArr; return o != null && type.Equals(o.type) && Patterns.ListMatch.DoMatch(this.Indices, o.Indices, ref match); @@ -4517,7 +4507,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDefaultValue(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as DefaultValue; return o != null && type.Equals(o.type); @@ -4554,7 +4544,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitThrow(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as Throw; return o != null && this.Argument.PerformMatch(o.Argument, ref match); @@ -4591,7 +4581,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitRethrow(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as Rethrow; return o != null; @@ -4633,7 +4623,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitSizeOf(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as SizeOf; return o != null && type.Equals(o.type); @@ -4646,7 +4636,7 @@ namespace ICSharpCode.Decompiler.IL public sealed partial class LdLen : ILInstruction { public static readonly SlotInfo ArraySlot = new SlotInfo("Array", canInlineInto: true); - ILInstruction array; + ILInstruction array = null!; public ILInstruction Array { get { return this.array; } set { @@ -4716,7 +4706,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdLen(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdLen; return o != null && this.array.PerformMatch(o.array, ref match); @@ -4724,7 +4714,7 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(array.ResultType == StackType.O); + DebugAssert(array.ResultType == StackType.O); } } } @@ -4747,7 +4737,7 @@ namespace ICSharpCode.Decompiler.IL set { type = value; InvalidateFlags(); } } public static readonly SlotInfo ArraySlot = new SlotInfo("Array", canInlineInto: true); - ILInstruction array; + ILInstruction array = null!; public ILInstruction Array { get { return this.array; } set { @@ -4848,7 +4838,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitLdElema(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as LdElema; return o != null && type.Equals(o.type) && this.array.PerformMatch(o.array, ref match) && Patterns.ListMatch.DoMatch(this.Indices, o.Indices, ref match) && this.WithSystemIndex == o.WithSystemIndex && DelayExceptions == o.DelayExceptions && IsReadOnly == o.IsReadOnly; @@ -4864,13 +4854,13 @@ namespace ICSharpCode.Decompiler.IL /// public sealed partial class GetPinnableReference : ILInstruction, IInstructionWithMethodOperand { - public GetPinnableReference(ILInstruction argument, IMethod method) : base(OpCode.GetPinnableReference) + public GetPinnableReference(ILInstruction argument, IMethod? method) : base(OpCode.GetPinnableReference) { this.Argument = argument; this.method = method; } public static readonly SlotInfo ArgumentSlot = new SlotInfo("Argument", canInlineInto: true); - ILInstruction argument; + ILInstruction argument = null!; public ILInstruction Argument { get { return this.argument; } set { @@ -4920,9 +4910,9 @@ namespace ICSharpCode.Decompiler.IL return clone; } public override StackType ResultType { get { return StackType.Ref; } } - readonly IMethod method; + readonly IMethod? method; /// Returns the method operand. - public IMethod Method { get { return method; } } + public IMethod? Method => method; protected override InstructionFlags ComputeFlags() { return argument.Flags; @@ -4957,7 +4947,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitGetPinnableReference(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as GetPinnableReference; return o != null && this.argument.PerformMatch(o.argument, ref match) && object.Equals(method, o.method); @@ -4965,7 +4955,7 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(argument.ResultType == StackType.O); + DebugAssert(argument.ResultType == StackType.O); } } } @@ -4975,7 +4965,7 @@ namespace ICSharpCode.Decompiler.IL public sealed partial class StringToInt : ILInstruction { public static readonly SlotInfo ArgumentSlot = new SlotInfo("Argument", canInlineInto: true); - ILInstruction argument; + ILInstruction argument = null!; public ILInstruction Argument { get { return this.argument; } set { @@ -5046,7 +5036,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitStringToInt(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as StringToInt; return o != null && this.argument.PerformMatch(o.argument, ref match); @@ -5054,7 +5044,7 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(argument.ResultType == StackType.O); + DebugAssert(argument.ResultType == StackType.O); } } } @@ -5091,7 +5081,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitExpressionTreeCast(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as ExpressionTreeCast; return o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type) && this.IsChecked == o.IsChecked; @@ -5111,10 +5101,10 @@ namespace ICSharpCode.Decompiler.IL } readonly IMethod method; /// Returns the method operand. - public IMethod Method { get { return method; } } + public IMethod Method => method; public override StackType ResultType { get { return StackType.O; } } public static readonly SlotInfo LeftSlot = new SlotInfo("Left", canInlineInto: true); - ILInstruction left; + ILInstruction left = null!; public ILInstruction Left { get { return this.left; } set { @@ -5123,7 +5113,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo RightSlot = new SlotInfo("Right"); - ILInstruction right; + ILInstruction right = null!; public ILInstruction Right { get { return this.right; } set { @@ -5207,7 +5197,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitUserDefinedLogicOperator(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as UserDefinedLogicOperator; return o != null && object.Equals(method, o.method) && this.left.PerformMatch(o.left, ref match) && this.right.PerformMatch(o.right, ref match); @@ -5220,7 +5210,7 @@ namespace ICSharpCode.Decompiler.IL public sealed partial class DynamicLogicOperatorInstruction : DynamicInstruction { public static readonly SlotInfo LeftSlot = new SlotInfo("Left", canInlineInto: true); - ILInstruction left; + ILInstruction left = null!; public ILInstruction Left { get { return this.left; } set { @@ -5229,7 +5219,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo RightSlot = new SlotInfo("Right"); - ILInstruction right; + ILInstruction right = null!; public ILInstruction Right { get { return this.right; } set { @@ -5298,7 +5288,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDynamicLogicOperatorInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as DynamicLogicOperatorInstruction; return o != null && this.left.PerformMatch(o.left, ref match) && this.right.PerformMatch(o.right, ref match); @@ -5311,7 +5301,7 @@ namespace ICSharpCode.Decompiler.IL public sealed partial class DynamicBinaryOperatorInstruction : DynamicInstruction { public static readonly SlotInfo LeftSlot = new SlotInfo("Left", canInlineInto: true); - ILInstruction left; + ILInstruction left = null!; public ILInstruction Left { get { return this.left; } set { @@ -5320,7 +5310,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo RightSlot = new SlotInfo("Right", canInlineInto: true); - ILInstruction right; + ILInstruction right = null!; public ILInstruction Right { get { return this.right; } set { @@ -5398,7 +5388,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDynamicBinaryOperatorInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as DynamicBinaryOperatorInstruction; return o != null && this.left.PerformMatch(o.left, ref match) && this.right.PerformMatch(o.right, ref match); @@ -5411,7 +5401,7 @@ namespace ICSharpCode.Decompiler.IL public sealed partial class DynamicUnaryOperatorInstruction : DynamicInstruction { public static readonly SlotInfo OperandSlot = new SlotInfo("Operand", canInlineInto: true); - ILInstruction operand; + ILInstruction operand = null!; public ILInstruction Operand { get { return this.operand; } set { @@ -5481,7 +5471,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDynamicUnaryOperatorInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as DynamicUnaryOperatorInstruction; return o != null && this.operand.PerformMatch(o.operand, ref match); @@ -5500,7 +5490,7 @@ namespace ICSharpCode.Decompiler.IL set { type = value; InvalidateFlags(); } } public static readonly SlotInfo ArgumentSlot = new SlotInfo("Argument", canInlineInto: true); - ILInstruction argument; + ILInstruction argument = null!; public ILInstruction Argument { get { return this.argument; } set { @@ -5570,7 +5560,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDynamicConvertInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as DynamicConvertInstruction; return o != null && type.Equals(o.type) && this.argument.PerformMatch(o.argument, ref match); @@ -5578,7 +5568,7 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(argument.ResultType == StackType.O); + DebugAssert(argument.ResultType == StackType.O); } } } @@ -5588,7 +5578,7 @@ namespace ICSharpCode.Decompiler.IL public sealed partial class DynamicGetMemberInstruction : DynamicInstruction { public static readonly SlotInfo TargetSlot = new SlotInfo("Target", canInlineInto: true); - ILInstruction target; + ILInstruction target = null!; public ILInstruction Target { get { return this.target; } set { @@ -5658,7 +5648,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDynamicGetMemberInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as DynamicGetMemberInstruction; return o != null && this.target.PerformMatch(o.target, ref match); @@ -5666,7 +5656,7 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(target.ResultType == StackType.O); + DebugAssert(target.ResultType == StackType.O); } } } @@ -5676,7 +5666,7 @@ namespace ICSharpCode.Decompiler.IL public sealed partial class DynamicSetMemberInstruction : DynamicInstruction { public static readonly SlotInfo TargetSlot = new SlotInfo("Target", canInlineInto: true); - ILInstruction target; + ILInstruction target = null!; public ILInstruction Target { get { return this.target; } set { @@ -5685,7 +5675,7 @@ namespace ICSharpCode.Decompiler.IL } } public static readonly SlotInfo ValueSlot = new SlotInfo("Value", canInlineInto: true); - ILInstruction value; + ILInstruction value = null!; public ILInstruction Value { get { return this.value; } set { @@ -5763,7 +5753,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDynamicSetMemberInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as DynamicSetMemberInstruction; return o != null && this.target.PerformMatch(o.target, ref match) && this.value.PerformMatch(o.value, ref match); @@ -5771,7 +5761,7 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(target.ResultType == StackType.O); + DebugAssert(target.ResultType == StackType.O); } } } @@ -5839,7 +5829,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDynamicGetIndexInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as DynamicGetIndexInstruction; return o != null && Patterns.ListMatch.DoMatch(this.Arguments, o.Arguments, ref match); @@ -5910,7 +5900,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDynamicSetIndexInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as DynamicSetIndexInstruction; return o != null && Patterns.ListMatch.DoMatch(this.Arguments, o.Arguments, ref match); @@ -5981,7 +5971,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDynamicInvokeMemberInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as DynamicInvokeMemberInstruction; return o != null && Patterns.ListMatch.DoMatch(this.Arguments, o.Arguments, ref match); @@ -6052,7 +6042,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDynamicInvokeConstructorInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as DynamicInvokeConstructorInstruction; return o != null && Patterns.ListMatch.DoMatch(this.Arguments, o.Arguments, ref match); @@ -6123,7 +6113,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDynamicInvokeInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as DynamicInvokeInstruction; return o != null && Patterns.ListMatch.DoMatch(this.Arguments, o.Arguments, ref match); @@ -6136,7 +6126,7 @@ namespace ICSharpCode.Decompiler.IL public sealed partial class DynamicIsEventInstruction : DynamicInstruction { public static readonly SlotInfo ArgumentSlot = new SlotInfo("Argument", canInlineInto: true); - ILInstruction argument; + ILInstruction argument = null!; public ILInstruction Argument { get { return this.argument; } set { @@ -6206,7 +6196,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDynamicIsEventInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as DynamicIsEventInstruction; return o != null && this.argument.PerformMatch(o.argument, ref match); @@ -6214,7 +6204,7 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(argument.ResultType == StackType.O); + DebugAssert(argument.ResultType == StackType.O); } } } @@ -6223,10 +6213,9 @@ namespace ICSharpCode.Decompiler.IL /// ILAst representation of C# patterns public sealed partial class MatchInstruction : ILInstruction, IStoreInstruction, IInstructionWithMethodOperand { - public MatchInstruction(ILVariable variable, IMethod method, ILInstruction testedOperand, params ILInstruction[] subPatterns) : base(OpCode.MatchInstruction) + public MatchInstruction(ILVariable variable, IMethod? method, ILInstruction testedOperand, params ILInstruction[] subPatterns) : base(OpCode.MatchInstruction) { - Debug.Assert(variable != null); - this.variable = variable; + this.variable = variable ?? throw new ArgumentNullException(nameof(variable)); this.method = method; this.TestedOperand = testedOperand; this.SubPatterns = new InstructionCollection(this, 1); @@ -6236,7 +6225,7 @@ namespace ICSharpCode.Decompiler.IL public ILVariable Variable { get { return variable; } set { - Debug.Assert(value != null); + DebugAssert(value != null); if (IsConnected) variable.RemoveStoreInstruction(this); variable = value; @@ -6264,15 +6253,15 @@ namespace ICSharpCode.Decompiler.IL base.Disconnected(); } - readonly IMethod method; + readonly IMethod? method; /// Returns the method operand. - public IMethod Method { get { return method; } } + public IMethod? Method => method; public bool IsDeconstructCall; public bool IsDeconstructTuple; public bool CheckType; public bool CheckNotNull; public static readonly SlotInfo TestedOperandSlot = new SlotInfo("TestedOperand", canInlineInto: true); - ILInstruction testedOperand; + ILInstruction testedOperand = null!; public ILInstruction TestedOperand { get { return this.testedOperand; } set { @@ -6348,7 +6337,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitMatchInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as MatchInstruction; return o != null && variable == o.variable && object.Equals(method, o.method) && this.IsDeconstructCall == o.IsDeconstructCall && this.IsDeconstructTuple == o.IsDeconstructTuple && this.CheckType == o.CheckType && this.CheckNotNull == o.CheckNotNull && this.testedOperand.PerformMatch(o.testedOperand, ref match) && Patterns.ListMatch.DoMatch(this.SubPatterns, o.SubPatterns, ref match); @@ -6356,8 +6345,8 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function)); - Debug.Assert(phase <= ILPhase.InILReader || variable.Function.Variables[variable.IndexInFunction] == variable); + DebugAssert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function!)); + DebugAssert(phase <= ILPhase.InILReader || variable.Function!.Variables[variable.IndexInFunction] == variable); AdditionalInvariants(); } } @@ -6400,7 +6389,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitMakeRefAny(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as MakeRefAny; return o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type); @@ -6428,7 +6417,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitRefAnyType(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as RefAnyType; return o != null && this.Argument.PerformMatch(o.Argument, ref match); @@ -6482,7 +6471,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitRefAnyValue(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as RefAnyValue; return o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type); @@ -6499,7 +6488,7 @@ namespace ICSharpCode.Decompiler.IL this.Value = value; } public static readonly SlotInfo ValueSlot = new SlotInfo("Value", canInlineInto: true); - ILInstruction value; + ILInstruction value = null!; public ILInstruction Value { get { return this.value; } set { @@ -6578,7 +6567,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitYieldReturn(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as YieldReturn; return o != null && this.value.PerformMatch(o.value, ref match); @@ -6595,7 +6584,7 @@ namespace ICSharpCode.Decompiler.IL this.Value = value; } public static readonly SlotInfo ValueSlot = new SlotInfo("Value", canInlineInto: true); - ILInstruction value; + ILInstruction value = null!; public ILInstruction Value { get { return this.value; } set { @@ -6674,7 +6663,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitAwait(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as Await; return o != null && this.value.PerformMatch(o.value, ref match); @@ -6699,7 +6688,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDeconstructInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as DeconstructInstruction; return o != null; @@ -6724,7 +6713,7 @@ namespace ICSharpCode.Decompiler.IL { return visitor.VisitDeconstructResultInstruction(this, context); } - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as DeconstructResultInstruction; return o != null && this.Argument.PerformMatch(o.Argument, ref match); @@ -8113,7 +8102,7 @@ namespace ICSharpCode.Decompiler.IL } return false; } - public bool MatchPinnedRegion(out ILVariable variable, out ILInstruction init, out ILInstruction body) + public bool MatchPinnedRegion([NotNullWhen(true)] out ILVariable? variable, [NotNullWhen(true)] out ILInstruction? init, [NotNullWhen(true)] out ILInstruction? body) { var inst = this as PinnedRegion; if (inst != null) @@ -8137,7 +8126,7 @@ namespace ICSharpCode.Decompiler.IL } return false; } - public bool MatchTryCatchHandler(out ILInstruction filter, out ILInstruction body, out ILVariable variable) + public bool MatchTryCatchHandler([NotNullWhen(true)] out ILInstruction? filter, [NotNullWhen(true)] out ILInstruction? body, [NotNullWhen(true)] out ILVariable? variable) { var inst = this as TryCatchHandler; if (inst != null) @@ -8152,7 +8141,7 @@ namespace ICSharpCode.Decompiler.IL variable = default(ILVariable); return false; } - public bool MatchLockInstruction(out ILInstruction onExpression, out ILInstruction body) + public bool MatchLockInstruction([NotNullWhen(true)] out ILInstruction? onExpression, [NotNullWhen(true)] out ILInstruction? body) { var inst = this as LockInstruction; if (inst != null) @@ -8165,7 +8154,7 @@ namespace ICSharpCode.Decompiler.IL body = default(ILInstruction); return false; } - public bool MatchUsingInstruction(out ILVariable variable, out ILInstruction resourceExpression, out ILInstruction body) + public bool MatchUsingInstruction([NotNullWhen(true)] out ILVariable? variable, [NotNullWhen(true)] out ILInstruction? resourceExpression, [NotNullWhen(true)] out ILInstruction? body) { var inst = this as UsingInstruction; if (inst != null) @@ -8189,7 +8178,7 @@ namespace ICSharpCode.Decompiler.IL } return false; } - public bool MatchCkfinite(out ILInstruction argument) + public bool MatchCkfinite([NotNullWhen(true)] out ILInstruction? argument) { var inst = this as Ckfinite; if (inst != null) @@ -8200,7 +8189,7 @@ namespace ICSharpCode.Decompiler.IL argument = default(ILInstruction); return false; } - public bool MatchLdLoc(out ILVariable variable) + public bool MatchLdLoc([NotNullWhen(true)] out ILVariable? variable) { var inst = this as LdLoc; if (inst != null) @@ -8211,7 +8200,7 @@ namespace ICSharpCode.Decompiler.IL variable = default(ILVariable); return false; } - public bool MatchLdLoca(out ILVariable variable) + public bool MatchLdLoca([NotNullWhen(true)] out ILVariable? variable) { var inst = this as LdLoca; if (inst != null) @@ -8222,7 +8211,7 @@ namespace ICSharpCode.Decompiler.IL variable = default(ILVariable); return false; } - public bool MatchStLoc(out ILVariable variable, out ILInstruction value) + public bool MatchStLoc([NotNullWhen(true)] out ILVariable? variable, [NotNullWhen(true)] out ILInstruction? value) { var inst = this as StLoc; if (inst != null) @@ -8235,7 +8224,7 @@ namespace ICSharpCode.Decompiler.IL value = default(ILInstruction); return false; } - public bool MatchAddressOf(out ILInstruction value, out IType type) + public bool MatchAddressOf([NotNullWhen(true)] out ILInstruction? value, [NotNullWhen(true)] out IType? type) { var inst = this as AddressOf; if (inst != null) @@ -8248,7 +8237,7 @@ namespace ICSharpCode.Decompiler.IL type = default(IType); return false; } - public bool MatchThreeValuedBoolAnd(out ILInstruction left, out ILInstruction right) + public bool MatchThreeValuedBoolAnd([NotNullWhen(true)] out ILInstruction? left, [NotNullWhen(true)] out ILInstruction? right) { var inst = this as ThreeValuedBoolAnd; if (inst != null) @@ -8261,7 +8250,7 @@ namespace ICSharpCode.Decompiler.IL right = default(ILInstruction); return false; } - public bool MatchThreeValuedBoolOr(out ILInstruction left, out ILInstruction right) + public bool MatchThreeValuedBoolOr([NotNullWhen(true)] out ILInstruction? left, [NotNullWhen(true)] out ILInstruction? right) { var inst = this as ThreeValuedBoolOr; if (inst != null) @@ -8274,7 +8263,7 @@ namespace ICSharpCode.Decompiler.IL right = default(ILInstruction); return false; } - public bool MatchNullableRewrap(out ILInstruction argument) + public bool MatchNullableRewrap([NotNullWhen(true)] out ILInstruction? argument) { var inst = this as NullableRewrap; if (inst != null) @@ -8285,7 +8274,7 @@ namespace ICSharpCode.Decompiler.IL argument = default(ILInstruction); return false; } - public bool MatchLdStr(out string value) + public bool MatchLdStr([NotNullWhen(true)] out string? value) { var inst = this as LdStr; if (inst != null) @@ -8360,7 +8349,7 @@ namespace ICSharpCode.Decompiler.IL } return false; } - public bool MatchLdFtn(out IMethod method) + public bool MatchLdFtn([NotNullWhen(true)] out IMethod? method) { var inst = this as LdFtn; if (inst != null) @@ -8371,7 +8360,7 @@ namespace ICSharpCode.Decompiler.IL method = default(IMethod); return false; } - public bool MatchLdVirtFtn(out ILInstruction argument, out IMethod method) + public bool MatchLdVirtFtn([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IMethod? method) { var inst = this as LdVirtFtn; if (inst != null) @@ -8384,7 +8373,7 @@ namespace ICSharpCode.Decompiler.IL method = default(IMethod); return false; } - public bool MatchLdVirtDelegate(out ILInstruction argument, out IType type, out IMethod method) + public bool MatchLdVirtDelegate([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type, [NotNullWhen(true)] out IMethod? method) { var inst = this as LdVirtDelegate; if (inst != null) @@ -8399,7 +8388,7 @@ namespace ICSharpCode.Decompiler.IL method = default(IMethod); return false; } - public bool MatchLdTypeToken(out IType type) + public bool MatchLdTypeToken([NotNullWhen(true)] out IType? type) { var inst = this as LdTypeToken; if (inst != null) @@ -8410,7 +8399,7 @@ namespace ICSharpCode.Decompiler.IL type = default(IType); return false; } - public bool MatchLdMemberToken(out IMember member) + public bool MatchLdMemberToken([NotNullWhen(true)] out IMember? member) { var inst = this as LdMemberToken; if (inst != null) @@ -8421,7 +8410,7 @@ namespace ICSharpCode.Decompiler.IL member = default(IMember); return false; } - public bool MatchLocAlloc(out ILInstruction argument) + public bool MatchLocAlloc([NotNullWhen(true)] out ILInstruction? argument) { var inst = this as LocAlloc; if (inst != null) @@ -8432,7 +8421,7 @@ namespace ICSharpCode.Decompiler.IL argument = default(ILInstruction); return false; } - public bool MatchLocAllocSpan(out ILInstruction argument, out IType type) + public bool MatchLocAllocSpan([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type) { var inst = this as LocAllocSpan; if (inst != null) @@ -8445,7 +8434,7 @@ namespace ICSharpCode.Decompiler.IL type = default(IType); return false; } - public bool MatchCpblk(out ILInstruction destAddress, out ILInstruction sourceAddress, out ILInstruction size) + public bool MatchCpblk([NotNullWhen(true)] out ILInstruction? destAddress, [NotNullWhen(true)] out ILInstruction? sourceAddress, [NotNullWhen(true)] out ILInstruction? size) { var inst = this as Cpblk; if (inst != null) @@ -8460,7 +8449,7 @@ namespace ICSharpCode.Decompiler.IL size = default(ILInstruction); return false; } - public bool MatchInitblk(out ILInstruction address, out ILInstruction value, out ILInstruction size) + public bool MatchInitblk([NotNullWhen(true)] out ILInstruction? address, [NotNullWhen(true)] out ILInstruction? value, [NotNullWhen(true)] out ILInstruction? size) { var inst = this as Initblk; if (inst != null) @@ -8475,7 +8464,7 @@ namespace ICSharpCode.Decompiler.IL size = default(ILInstruction); return false; } - public bool MatchLdFlda(out ILInstruction target, out IField field) + public bool MatchLdFlda([NotNullWhen(true)] out ILInstruction? target, [NotNullWhen(true)] out IField? field) { var inst = this as LdFlda; if (inst != null) @@ -8488,7 +8477,7 @@ namespace ICSharpCode.Decompiler.IL field = default(IField); return false; } - public bool MatchLdsFlda(out IField field) + public bool MatchLdsFlda([NotNullWhen(true)] out IField? field) { var inst = this as LdsFlda; if (inst != null) @@ -8499,7 +8488,7 @@ namespace ICSharpCode.Decompiler.IL field = default(IField); return false; } - public bool MatchCastClass(out ILInstruction argument, out IType type) + public bool MatchCastClass([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type) { var inst = this as CastClass; if (inst != null) @@ -8512,7 +8501,7 @@ namespace ICSharpCode.Decompiler.IL type = default(IType); return false; } - public bool MatchIsInst(out ILInstruction argument, out IType type) + public bool MatchIsInst([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type) { var inst = this as IsInst; if (inst != null) @@ -8525,7 +8514,7 @@ namespace ICSharpCode.Decompiler.IL type = default(IType); return false; } - public bool MatchLdObj(out ILInstruction target, out IType type) + public bool MatchLdObj([NotNullWhen(true)] out ILInstruction? target, [NotNullWhen(true)] out IType? type) { var inst = this as LdObj; if (inst != null) @@ -8538,7 +8527,7 @@ namespace ICSharpCode.Decompiler.IL type = default(IType); return false; } - public bool MatchStObj(out ILInstruction target, out ILInstruction value, out IType type) + public bool MatchStObj([NotNullWhen(true)] out ILInstruction? target, [NotNullWhen(true)] out ILInstruction? value, [NotNullWhen(true)] out IType? type) { var inst = this as StObj; if (inst != null) @@ -8553,7 +8542,7 @@ namespace ICSharpCode.Decompiler.IL type = default(IType); return false; } - public bool MatchBox(out ILInstruction argument, out IType type) + public bool MatchBox([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type) { var inst = this as Box; if (inst != null) @@ -8566,7 +8555,7 @@ namespace ICSharpCode.Decompiler.IL type = default(IType); return false; } - public bool MatchUnbox(out ILInstruction argument, out IType type) + public bool MatchUnbox([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type) { var inst = this as Unbox; if (inst != null) @@ -8579,7 +8568,7 @@ namespace ICSharpCode.Decompiler.IL type = default(IType); return false; } - public bool MatchUnboxAny(out ILInstruction argument, out IType type) + public bool MatchUnboxAny([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type) { var inst = this as UnboxAny; if (inst != null) @@ -8592,7 +8581,7 @@ namespace ICSharpCode.Decompiler.IL type = default(IType); return false; } - public bool MatchNewArr(out IType type) + public bool MatchNewArr([NotNullWhen(true)] out IType? type) { var inst = this as NewArr; if (inst != null) @@ -8603,7 +8592,7 @@ namespace ICSharpCode.Decompiler.IL type = default(IType); return false; } - public bool MatchDefaultValue(out IType type) + public bool MatchDefaultValue([NotNullWhen(true)] out IType? type) { var inst = this as DefaultValue; if (inst != null) @@ -8614,7 +8603,7 @@ namespace ICSharpCode.Decompiler.IL type = default(IType); return false; } - public bool MatchThrow(out ILInstruction argument) + public bool MatchThrow([NotNullWhen(true)] out ILInstruction? argument) { var inst = this as Throw; if (inst != null) @@ -8634,7 +8623,7 @@ namespace ICSharpCode.Decompiler.IL } return false; } - public bool MatchSizeOf(out IType type) + public bool MatchSizeOf([NotNullWhen(true)] out IType? type) { var inst = this as SizeOf; if (inst != null) @@ -8645,7 +8634,7 @@ namespace ICSharpCode.Decompiler.IL type = default(IType); return false; } - public bool MatchLdElema(out IType type, out ILInstruction array) + public bool MatchLdElema([NotNullWhen(true)] out IType? type, [NotNullWhen(true)] out ILInstruction? array) { var inst = this as LdElema; if (inst != null) @@ -8658,7 +8647,7 @@ namespace ICSharpCode.Decompiler.IL array = default(ILInstruction); return false; } - public bool MatchGetPinnableReference(out ILInstruction argument, out IMethod method) + public bool MatchGetPinnableReference([NotNullWhen(true)] out ILInstruction? argument, out IMethod? method) { var inst = this as GetPinnableReference; if (inst != null) @@ -8668,10 +8657,10 @@ namespace ICSharpCode.Decompiler.IL return true; } argument = default(ILInstruction); - method = default(IMethod); + method = default(IMethod?); return false; } - public bool MatchUserDefinedLogicOperator(out IMethod method, out ILInstruction left, out ILInstruction right) + public bool MatchUserDefinedLogicOperator([NotNullWhen(true)] out IMethod? method, [NotNullWhen(true)] out ILInstruction? left, [NotNullWhen(true)] out ILInstruction? right) { var inst = this as UserDefinedLogicOperator; if (inst != null) @@ -8686,7 +8675,7 @@ namespace ICSharpCode.Decompiler.IL right = default(ILInstruction); return false; } - public bool MatchMatchInstruction(out ILVariable variable, out IMethod method, out ILInstruction testedOperand) + public bool MatchMatchInstruction([NotNullWhen(true)] out ILVariable? variable, out IMethod? method, [NotNullWhen(true)] out ILInstruction? testedOperand) { var inst = this as MatchInstruction; if (inst != null) @@ -8697,11 +8686,11 @@ namespace ICSharpCode.Decompiler.IL return true; } variable = default(ILVariable); - method = default(IMethod); + method = default(IMethod?); testedOperand = default(ILInstruction); return false; } - public bool MatchMakeRefAny(out ILInstruction argument, out IType type) + public bool MatchMakeRefAny([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type) { var inst = this as MakeRefAny; if (inst != null) @@ -8714,7 +8703,7 @@ namespace ICSharpCode.Decompiler.IL type = default(IType); return false; } - public bool MatchRefAnyType(out ILInstruction argument) + public bool MatchRefAnyType([NotNullWhen(true)] out ILInstruction? argument) { var inst = this as RefAnyType; if (inst != null) @@ -8725,7 +8714,7 @@ namespace ICSharpCode.Decompiler.IL argument = default(ILInstruction); return false; } - public bool MatchRefAnyValue(out ILInstruction argument, out IType type) + public bool MatchRefAnyValue([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type) { var inst = this as RefAnyValue; if (inst != null) @@ -8738,7 +8727,7 @@ namespace ICSharpCode.Decompiler.IL type = default(IType); return false; } - public bool MatchYieldReturn(out ILInstruction value) + public bool MatchYieldReturn([NotNullWhen(true)] out ILInstruction? value) { var inst = this as YieldReturn; if (inst != null) @@ -8749,7 +8738,7 @@ namespace ICSharpCode.Decompiler.IL value = default(ILInstruction); return false; } - public bool MatchAwait(out ILInstruction value) + public bool MatchAwait([NotNullWhen(true)] out ILInstruction? value) { var inst = this as Await; if (inst != null) @@ -8762,4 +8751,3 @@ namespace ICSharpCode.Decompiler.IL } } } - diff --git a/ICSharpCode.Decompiler/IL/Instructions.tt b/ICSharpCode.Decompiler/IL/Instructions.tt index 1ee7195a5..18a4cf4c4 100644 --- a/ICSharpCode.Decompiler/IL/Instructions.tt +++ b/ICSharpCode.Decompiler/IL/Instructions.tt @@ -16,6 +16,8 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#nullable enable + <#@ template debug="false" hostspecific="false" language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> @@ -32,7 +34,7 @@ AbstractBaseClass, CustomArguments(("left", null), ("right", null)), HasFlag("InstructionFlags.None")), new OpCode("CallInstruction", "Instruction with a list of arguments.", AbstractBaseClass, CustomChildren(new []{ new ArgumentInfo("arguments") { IsCollection = true }}), - CustomWriteTo, MayThrow, SideEffect), + CustomConstructor, CustomWriteTo, MayThrow, SideEffect), new OpCode("PatternInstruction", "Base class for pattern matching in ILAst.", AbstractBaseClass, ResultType("Unknown")) { Namespace = "ICSharpCode.Decompiler.IL.Patterns" }, new OpCode("CompoundAssignmentInstruction", "Common instruction for compound assignments.", AbstractBaseClass, CustomConstructor, CustomArguments(("target", null), ("value", null))), @@ -68,7 +70,7 @@ new ChildInfo("init") { CanInlineInto = true }, new ChildInfo("body") }), - CustomInvariant("Debug.Assert(Variable.Kind == VariableKind.PinnedRegionLocal);")), + CustomInvariant("DebugAssert(Variable.Kind == VariableKind.PinnedRegionLocal);")), new OpCode("binary", "Common instruction for add, sub, mul, div, rem, bit.and, bit.or, bit.xor, shl and shr.", CustomClassName("BinaryNumericInstruction"), Binary, CustomWriteTo, CustomConstructor, CustomComputeFlags, MatchCondition("CheckForOverflow == o.CheckForOverflow && Sign == o.Sign && Operator == o.Operator && IsLifted == o.IsLifted")), @@ -215,11 +217,11 @@ new OpCode("ldnull", "Loads the null reference.", CustomClassName("LdNull"), NoArguments, ResultType("O")), new OpCode("ldftn", "Load method pointer", - CustomClassName("LdFtn"), NoArguments, HasMethodOperand, ResultType("I")), + CustomClassName("LdFtn"), NoArguments, HasMethodOperand(), ResultType("I")), new OpCode("ldvirtftn", "Load method pointer", - CustomClassName("LdVirtFtn"), Unary, HasMethodOperand, MayThrow, ResultType("I")), + CustomClassName("LdVirtFtn"), Unary, HasMethodOperand(), MayThrow, ResultType("I")), new OpCode("ldvirtdelegate", "Virtual delegate construction", - CustomClassName("LdVirtDelegate"), Unary, HasTypeOperand, HasMethodOperand, + CustomClassName("LdVirtDelegate"), Unary, HasTypeOperand, HasMethodOperand(), MayThrow, ResultType("O")), new OpCode("ldtypetoken", "Loads runtime representation of metadata token", CustomClassName("LdTypeToken"), NoArguments, HasTypeOperand, ResultType("O")), @@ -287,7 +289,7 @@ + "The input must be an object reference (O)." + Environment.NewLine + "If the input is an array/string, evaluates to a reference to the first element/character, or to a null reference if the array is null or empty." + Environment.NewLine + "Otherwise, uses the GetPinnableReference method to get the reference, or evaluates to a null reference if the input is null." + Environment.NewLine, - CustomArguments(("argument", new[] { "O" })), ResultType("Ref"), HasMethodOperand), + CustomArguments(("argument", new[] { "O" })), ResultType("Ref"), HasMethodOperand(nullable: true)), new OpCode("string.to.int", "Maps a string value to an integer. This is used in switch(string).", CustomArguments(("argument", new[] { "O" })), CustomConstructor, CustomWriteTo, ResultType("I4")), @@ -297,7 +299,7 @@ new OpCode("user.logic.operator", "Use of user-defined && or || operator.", CustomClassName("UserDefinedLogicOperator"), - HasMethodOperand, ResultType("O"), + HasMethodOperand(), ResultType("O"), CustomChildren(new []{ new ChildInfo("left") { CanInlineInto = true }, new ChildInfo("right") { CanInlineInto = false } // only executed depending on value of left @@ -337,7 +339,7 @@ CustomClassName("DynamicIsEventInstruction"), Dynamic, CustomArguments(("argument", new[] { "O" })), CustomWriteTo), new OpCode("match", "ILAst representation of C# patterns", - CustomClassName("MatchInstruction"), HasVariableOperand("Store"), HasMethodOperand, + CustomClassName("MatchInstruction"), HasVariableOperand("Store"), HasMethodOperand(nullable: true), BoolFlag("IsDeconstructCall"), BoolFlag("IsDeconstructTuple"), BoolFlag("CheckType"), BoolFlag("CheckNotNull"), CustomChildren(new []{ new ChildInfo("testedOperand") { CanInlineInto = true }, @@ -371,8 +373,8 @@ }; #> using System; -using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using ICSharpCode.Decompiler.TypeSystem; @@ -437,7 +439,7 @@ namespace <#=opCode.Namespace#> } <# } #> <# if (opCode.GeneratePerformMatch) { #> - protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) { var o = other as <#=opCode.Name#>; return <#=string.Join(" && ", opCode.PerformMatchConditions)#>; @@ -637,10 +639,15 @@ namespace ICSharpCode.Decompiler.IL public string TypeName; public string Name; public string FieldName; + public bool IsReferenceType = true; public override string ToString() { - return "out " + TypeName + " " + Name; + if (IsReferenceType) { + return "[NotNullWhen(true)] out " + TypeName + "? " + Name; + } else { + return "out " + TypeName + " " + Name; + } } } @@ -866,7 +873,7 @@ namespace ICSharpCode.Decompiler.IL opCode.WriteArguments.Add("output.Write(\", \");"); opCode.WriteArguments.Add("this." + arg + ".WriteTo(output, options);"); opCode.Members.Add("public static readonly SlotInfo " + children[i].SlotName + " = " + children[i].GetSlotInit() + ";"); - opCode.Members.Add("ILInstruction " + arg + ";"); + opCode.Members.Add("ILInstruction " + arg + " = null!;"); opCode.Members.Add("public ILInstruction " + argProp + " {" + Environment.NewLine + "\tget { return this." + arg + "; }" + Environment.NewLine + "\tset {" + Environment.NewLine @@ -885,7 +892,7 @@ namespace ICSharpCode.Decompiler.IL checkString += " || "; checkString += arg + ".ResultType == " + expectedTypeCode; } - opCode.Invariants.Add("Debug.Assert(" + checkString + ");"); + opCode.Invariants.Add("DebugAssert(" + checkString + ");"); } } opCode.WriteArguments.Add("output.Write(')');"); @@ -1008,8 +1015,7 @@ namespace ICSharpCode.Decompiler.IL Action action = opCode => { opCode.ConstructorParameters.Add("ILVariable variable"); opCode.Members.Add("ILVariable variable;"); - opCode.ConstructorBody.Add("Debug.Assert(variable != null);"); - opCode.ConstructorBody.Add("this.variable = variable;"); + opCode.ConstructorBody.Add("this.variable = variable ?? throw new ArgumentNullException(nameof(variable));"); opCode.MatchParameters.Add(new MatchParamInfo { TypeName = "ILVariable", Name = "variable", FieldName = "Variable" }); opCode.PerformMatchConditions.Add("variable == o.variable"); opCode.GenerateWriteTo = true; @@ -1019,7 +1025,7 @@ namespace ICSharpCode.Decompiler.IL opCode.Members.Add(@"public ILVariable Variable { get { return variable; } set { - Debug.Assert(value != null); + DebugAssert(value != null); if (IsConnected) variable.RemoveAccessInstruction(this); variable = value; @@ -1048,8 +1054,8 @@ protected override void Disconnected() } ".Replace("Access", accessType)); if (generateCheckInvariant) { - opCode.Invariants.Add("Debug.Assert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function));"); - opCode.Invariants.Add("Debug.Assert(phase <= ILPhase.InILReader || variable.Function.Variables[variable.IndexInFunction] == variable);"); + opCode.Invariants.Add("DebugAssert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function!));"); + opCode.Invariants.Add("DebugAssert(phase <= ILPhase.InILReader || variable.Function!.Variables[variable.IndexInFunction] == variable);"); } }; if (accessType == "Load") { @@ -1093,22 +1099,26 @@ protected override void Disconnected() opCode.WriteOperand.Add("type.WriteTo(output);"); }; - static Action HasMethodOperand = opCode => { - opCode.ConstructorParameters.Add("IMethod method"); - opCode.Members.Add("readonly IMethod method;"); - opCode.ConstructorBody.Add("this.method = method;"); - opCode.MatchParameters.Add(new MatchParamInfo { TypeName = "IMethod", Name = "method", FieldName = "Method" }); - opCode.PerformMatchConditions.Add("object.Equals(method, o.method)"); - opCode.Members.Add("/// Returns the method operand." + Environment.NewLine - + "public IMethod Method { get { return method; } }"); - opCode.GenerateWriteTo = true; - opCode.WriteOperand.Add("if (method != null) {"); - opCode.WriteOperand.Add("\toutput.Write(' ');"); - opCode.WriteOperand.Add("\tmethod.WriteTo(output);"); - opCode.WriteOperand.Add("}"); - opCode.Interfaces.Add("IInstructionWithMethodOperand"); - }; - + static Action HasMethodOperand(bool nullable = false) + { + return opCode => { + string n = nullable ? "?" : ""; + opCode.ConstructorParameters.Add($"IMethod{n} method"); + opCode.Members.Add($"readonly IMethod{n} method;"); + opCode.ConstructorBody.Add("this.method = method;"); + opCode.MatchParameters.Add(new MatchParamInfo { TypeName = $"IMethod{n}", Name = "method", FieldName = "Method", IsReferenceType = !nullable }); + opCode.PerformMatchConditions.Add("object.Equals(method, o.method)"); + opCode.Members.Add("/// Returns the method operand." + Environment.NewLine + + $"public IMethod{n} Method => method;"); + opCode.GenerateWriteTo = true; + opCode.WriteOperand.Add("if (method != null) {"); + opCode.WriteOperand.Add("\toutput.Write(' ');"); + opCode.WriteOperand.Add("\tmethod.WriteTo(output);"); + opCode.WriteOperand.Add("}"); + opCode.Interfaces.Add("IInstructionWithMethodOperand"); + }; + } + static Action HasMemberOperand = opCode => { opCode.ConstructorParameters.Add("IMember member"); opCode.Members.Add("readonly IMember member;"); @@ -1139,7 +1149,12 @@ protected override void Disconnected() return opCode => { NoArguments(opCode); opCode.ConstructorParameters.Add(operandType + " value"); - opCode.MatchParameters.Add(new MatchParamInfo { TypeName = operandType, Name = "value", FieldName = "Value" }); + opCode.MatchParameters.Add(new MatchParamInfo { + TypeName = operandType, + Name = "value", + FieldName = "Value", + IsReferenceType = operandType == "string" + }); opCode.PerformMatchConditions.Add("this.Value == o.Value"); opCode.Members.Add("public readonly " + operandType + " Value;"); opCode.ConstructorBody.Add("this.Value = value;"); diff --git a/ICSharpCode.Decompiler/IL/Instructions/Block.cs b/ICSharpCode.Decompiler/IL/Instructions/Block.cs index 11e1b1d33..cd0b43d4c 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Block.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Block.cs @@ -124,10 +124,10 @@ namespace ICSharpCode.Decompiler.IL foreach (var inst in Instructions) { var stloc = inst as StLoc; - Debug.Assert(stloc != null, "Instructions in CallWithNamedArgs must be assignments"); - Debug.Assert(stloc!.Variable.Kind == VariableKind.NamedArgument); - Debug.Assert(stloc.Variable.IsSingleDefinition && stloc.Variable.LoadCount == 1); - Debug.Assert(stloc.Variable.LoadInstructions.Single().Parent == finalInstruction); + DebugAssert(stloc != null, "Instructions in CallWithNamedArgs must be assignments"); + DebugAssert(stloc.Variable.Kind == VariableKind.NamedArgument); + DebugAssert(stloc.Variable.IsSingleDefinition && stloc.Variable.LoadCount == 1); + DebugAssert(stloc.Variable.LoadInstructions.Single().Parent == finalInstruction); } var call = (CallInstruction)finalInstruction; if (call.IsInstanceCall) @@ -144,9 +144,9 @@ namespace ICSharpCode.Decompiler.IL Debug.Assert(Instructions[0].MatchStLoc(final!.Variable, out var init) && init.MatchNewArr(out type)); for (int i = 1; i < Instructions.Count; i++) { - Debug.Assert(Instructions[i].MatchStObj(out ILInstruction? target, out _, out var t) && type != null && type.Equals(t)); - Debug.Assert(target.MatchLdElema(out t, out ILInstruction? array) && type!.Equals(t)); - Debug.Assert(array.MatchLdLoc(out ILVariable? v) && v == final.Variable); + DebugAssert(Instructions[i].MatchStObj(out ILInstruction? target, out _, out var t) && type != null && type.Equals(t)); + DebugAssert(target.MatchLdElema(out t, out ILInstruction? array) && type.Equals(t)); + DebugAssert(array.MatchLdLoc(out ILVariable? v) && v == final.Variable); } break; case BlockKind.CollectionInitializer: diff --git a/ICSharpCode.Decompiler/IL/Instructions/DeconstructResultInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/DeconstructResultInstruction.cs index 5d04588e7..874345a6a 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/DeconstructResultInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/DeconstructResultInstruction.cs @@ -61,10 +61,10 @@ namespace ICSharpCode.Decompiler.IL void AdditionalInvariants() { var matchInst = FindMatch(); - Debug.Assert(matchInst != null && (matchInst.IsDeconstructCall || matchInst.IsDeconstructTuple)); - Debug.Assert(Argument.MatchLdLoc(matchInst!.Variable)); + DebugAssert(matchInst != null && (matchInst.IsDeconstructCall || matchInst.IsDeconstructTuple)); + DebugAssert(Argument.MatchLdLoc(matchInst.Variable)); var outParamType = matchInst.GetDeconstructResultType(this.Index); - Debug.Assert(outParamType.GetStackType() == ResultType); + DebugAssert(outParamType.GetStackType() == ResultType); } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs b/ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs index 09e116b19..9c3587c1c 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs @@ -145,7 +145,7 @@ namespace ICSharpCode.Decompiler.IL public DynamicConvertInstruction(CSharpBinderFlags binderFlags, IType type, IType? context, ILInstruction argument) : base(OpCode.DynamicConvertInstruction, binderFlags, context) { - Type = type; + this.type = type; Argument = argument; } diff --git a/ICSharpCode.Decompiler/IL/Instructions/ExpressionTreeCast.cs b/ICSharpCode.Decompiler/IL/Instructions/ExpressionTreeCast.cs index c5684cc62..ba70db9cd 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ExpressionTreeCast.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/ExpressionTreeCast.cs @@ -1,8 +1,4 @@ #nullable enable -using System; -using System.Collections.Generic; -using System.Text; - using ICSharpCode.Decompiler.TypeSystem; namespace ICSharpCode.Decompiler.IL @@ -14,7 +10,7 @@ namespace ICSharpCode.Decompiler.IL public ExpressionTreeCast(IType type, ILInstruction argument, bool isChecked) : base(OpCode.ExpressionTreeCast, argument) { - this.Type = type; + this.type = type; this.IsChecked = isChecked; } diff --git a/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs index 4bb282025..b705a3a70 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs @@ -21,6 +21,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Threading; using ICSharpCode.Decompiler.IL.Patterns; @@ -70,6 +71,16 @@ namespace ICSharpCode.Decompiler.IL // make sure to read the remarks on the ReplaceWith() method. } + internal static void DebugAssert([DoesNotReturnIf(false)] bool b) + { + Debug.Assert(b); + } + + internal static void DebugAssert([DoesNotReturnIf(false)] bool b, string msg) + { + Debug.Assert(b, msg); + } + [Conditional("DEBUG")] internal virtual void CheckInvariant(ILPhase phase) { @@ -494,7 +505,7 @@ namespace ICSharpCode.Decompiler.IL internal ChildrenEnumerator(ILInstruction inst) { - Debug.Assert(inst != null); + DebugAssert(inst != null); this.inst = inst; this.pos = -1; this.end = inst!.GetChildCount(); @@ -951,7 +962,7 @@ namespace ICSharpCode.Decompiler.IL public interface IInstructionWithMethodOperand { - IMethod Method { get; } + IMethod? Method { get; } } public interface ILiftableInstruction diff --git a/ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs index 6280849f8..e5833cd16 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs @@ -96,7 +96,7 @@ namespace ICSharpCode.Decompiler.IL public int NumPositionalPatterns { get { if (IsDeconstructCall) - return method.Parameters.Count - (method.IsStatic ? 1 : 0); + return method!.Parameters.Count - (method.IsStatic ? 1 : 0); else if (IsDeconstructTuple) return TupleType.GetTupleElementTypes(variable.Type).Length; else @@ -104,7 +104,7 @@ namespace ICSharpCode.Decompiler.IL } } - public MatchInstruction(ILVariable variable, ILInstruction? testedOperand) + public MatchInstruction(ILVariable variable, ILInstruction testedOperand) : this(variable, method: null, testedOperand) { } @@ -153,9 +153,9 @@ namespace ICSharpCode.Decompiler.IL { if (this.IsDeconstructCall) { - int firstOutParam = (method.IsStatic ? 1 : 0); - var outParamType = this.Method.Parameters[firstOutParam + index].Type; - if (!(outParamType is ByReferenceType brt)) + int firstOutParam = (method!.IsStatic ? 1 : 0); + var outParamType = method.Parameters[firstOutParam + index].Type; + if (outParamType is not ByReferenceType brt) throw new InvalidOperationException("deconstruct out param must be by reference"); return brt.ElementType; } @@ -210,8 +210,11 @@ namespace ICSharpCode.Decompiler.IL } } - internal static bool IsDeconstructMethod(IMethod method) + internal static bool IsDeconstructMethod(IMethod? method) { + if (method == null + ) + return false; if (method.Name != "Deconstruct") return false; if (method.ReturnType.Kind != TypeKind.Void) @@ -260,7 +263,10 @@ namespace ICSharpCode.Decompiler.IL if (IsDeconstructCall) { output.Write(".deconstruct["); - method.WriteTo(output); + if (method == null) + output.Write(""); + else + method.WriteTo(output); output.Write(']'); } if (IsDeconstructTuple) diff --git a/ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs b/ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs index f8e041fcf..61b5f99c6 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs @@ -26,14 +26,14 @@ namespace ICSharpCode.Decompiler.IL { public List<(string? Key, int Value)> Map { get; } - public StringToInt(ILInstruction? argument, List<(string? Key, int Value)> map) + public StringToInt(ILInstruction argument, List<(string? Key, int Value)> map) : base(OpCode.StringToInt) { this.Argument = argument; this.Map = map; } - public StringToInt(ILInstruction? argument, string?[] map) + public StringToInt(ILInstruction argument, string?[] map) : this(argument, ArrayToDictionary(map)) { } diff --git a/ICSharpCode.Decompiler/Util/NullAttributes.cs b/ICSharpCode.Decompiler/Util/NullAttributes.cs index 4639c3dae..18662c4e7 100644 --- a/ICSharpCode.Decompiler/Util/NullAttributes.cs +++ b/ICSharpCode.Decompiler/Util/NullAttributes.cs @@ -25,5 +25,13 @@ namespace System.Diagnostics.CodeAnalysis public bool ReturnValue { get; } } + + [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] + internal sealed class DoesNotReturnIfAttribute : Attribute + { + public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue; + + public bool ParameterValue { get; } + } } #endif From ffed8ea2c8504db4503a609e6dfd81bc0cce0848 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 5 Jun 2021 18:48:41 +0200 Subject: [PATCH 6/6] #nullable enable for AstNode --- ICSharpCode.Decompiler/CSharp/CallBuilder.cs | 2 +- .../CSharp/Syntax/AstNode.cs | 143 +++++++++--------- .../CSharp/Syntax/ComposedType.cs | 3 +- .../Expressions/ArrayCreateExpression.cs | 2 +- .../Syntax/Expressions/QueryExpression.cs | 8 +- .../Syntax/Expressions/SwitchExpression.cs | 2 +- .../GeneralScope/PreProcessorDirective.cs | 3 +- ICSharpCode.Decompiler/CSharp/Syntax/Role.cs | 12 +- ICSharpCode.Decompiler/CSharp/Syntax/Roles.cs | 14 +- .../LocalFunctionDeclarationStatement.cs | 2 +- .../Syntax/Statements/SwitchStatement.cs | 4 +- .../Syntax/TypeMembers/EntityDeclaration.cs | 4 +- .../TypeMembers/FixedFieldDeclaration.cs | 3 +- 13 files changed, 99 insertions(+), 103 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs index ff5122676..7cf420ba7 100644 --- a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs @@ -543,7 +543,7 @@ namespace ICSharpCode.Decompiler.CSharp argumentList.Arguments.ToList(), argumentList.ArgumentNames); if (((AssignmentExpression)assignment).Left is IndexerExpression indexer && !indexer.Target.IsNull) - indexer.Target.ReplaceWith(n => null); + indexer.Target.Remove(); if (value != null) return assignment; diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/AstNode.cs b/ICSharpCode.Decompiler/CSharp/Syntax/AstNode.cs index 91a05b3e2..b23183c6d 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/AstNode.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/AstNode.cs @@ -1,4 +1,5 @@ -// +#nullable enable +// // AstNode.cs // // Author: @@ -39,7 +40,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax public abstract class AstNode : AbstractAnnotatable, IFreezable, INode, ICloneable { // the Root role must be available when creating the null nodes, so we can't put it in the Roles class - internal static readonly Role RootRole = new Role("Root"); + internal static readonly Role RootRole = new Role("Root", null); #region Null public static readonly AstNode Null = new NullAstNode(); @@ -73,7 +74,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax return visitor.VisitNullNode(this, data); } - protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + protected internal override bool DoMatch(AstNode? other, PatternMatching.Match match) { return other == null || other.IsNull; } @@ -81,7 +82,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax #endregion #region PatternPlaceholder - public static implicit operator AstNode(PatternMatching.Pattern pattern) + public static implicit operator AstNode?(PatternMatching.Pattern? pattern) { return pattern != null ? new PatternPlaceholder(pattern) : null; } @@ -114,23 +115,23 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax return visitor.VisitPatternPlaceholder(this, child, data); } - protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + protected internal override bool DoMatch(AstNode? other, PatternMatching.Match match) { return child.DoMatch(other, match); } - bool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo) + bool PatternMatching.INode.DoMatchCollection(Role? role, PatternMatching.INode? pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo) { return child.DoMatchCollection(role, pos, match, backtrackingInfo); } } #endregion - AstNode parent; - AstNode prevSibling; - AstNode nextSibling; - AstNode firstChild; - AstNode lastChild; + AstNode? parent; + AstNode? prevSibling; + AstNode? nextSibling; + AstNode? firstChild; + AstNode? lastChild; // Flags, from least significant to most significant bits: // - Role.RoleIndexBits: role index @@ -157,7 +158,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax { if (!IsFrozen) { - for (AstNode child = firstChild; child != null; child = child.nextSibling) + for (AstNode? child = firstChild; child != null; child = child.nextSibling) child.Freeze(); flags |= frozenBit; } @@ -197,7 +198,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax } } - public AstNode Parent { + public AstNode? Parent { get { return parent; } } @@ -224,19 +225,19 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax flags = (flags & ~roleIndexMask) | role.Index; } - public AstNode NextSibling { + public AstNode? NextSibling { get { return nextSibling; } } - public AstNode PrevSibling { + public AstNode? PrevSibling { get { return prevSibling; } } - public AstNode FirstChild { + public AstNode? FirstChild { get { return firstChild; } } - public AstNode LastChild { + public AstNode? LastChild { get { return lastChild; } } @@ -248,8 +249,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax public IEnumerable Children { get { - AstNode next; - for (AstNode cur = firstChild; cur != null; cur = next) + AstNode? next; + for (AstNode? cur = firstChild; cur != null; cur = next) { Debug.Assert(cur.parent == this); // Remember next before yielding cur. @@ -265,7 +266,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// public IEnumerable Ancestors { get { - for (AstNode cur = parent; cur != null; cur = cur.parent) + for (AstNode? cur = parent; cur != null; cur = cur.parent) { yield return cur; } @@ -277,7 +278,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// public IEnumerable AncestorsAndSelf { get { - for (AstNode cur = this; cur != null; cur = cur.parent) + for (AstNode? cur = this; cur != null; cur = cur.parent) { yield return cur; } @@ -298,18 +299,18 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax get { return GetDescendantsImpl(true); } } - public IEnumerable DescendantNodes(Func descendIntoChildren = null) + public IEnumerable DescendantNodes(Func? descendIntoChildren = null) { return GetDescendantsImpl(false, descendIntoChildren); } - public IEnumerable DescendantNodesAndSelf(Func descendIntoChildren = null) + public IEnumerable DescendantNodesAndSelf(Func? descendIntoChildren = null) { return GetDescendantsImpl(true, descendIntoChildren); } - IEnumerable GetDescendantsImpl(bool includeSelf, Func descendIntoChildren = null) + IEnumerable GetDescendantsImpl(bool includeSelf, Func? descendIntoChildren = null) { if (includeSelf) { @@ -318,9 +319,9 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax yield break; } - Stack nextStack = new Stack(); + Stack nextStack = new Stack(); nextStack.Push(null); - AstNode pos = firstChild; + AstNode? pos = firstChild; while (pos != null) { // Remember next before yielding pos. @@ -339,7 +340,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// Gets the first child with the specified role. /// Returns the role's null object if the child is not found. /// - public T GetChildByRole(Role role) where T : AstNode + public T GetChildByRole(Role role) where T : AstNode? { if (role == null) throw new ArgumentNullException(nameof(role)); @@ -352,12 +353,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax return role.NullObject; } - public T GetParent() where T : AstNode + public T? GetParent() where T : AstNode { return Ancestors.OfType().FirstOrDefault(); } - public AstNode GetParent(Func pred) + public AstNode GetParent(Func? pred) { return Ancestors.FirstOrDefault(pred); } @@ -392,7 +393,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax AddChildUnsafe(child, role); } - public void AddChildWithExistingRole(AstNode child) + public void AddChildWithExistingRole(AstNode? child) { if (child == null || child.IsNull) return; @@ -419,13 +420,13 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax } else { - lastChild.nextSibling = child; + lastChild!.nextSibling = child; child.prevSibling = lastChild; lastChild = child; } } - public void InsertChildBefore(AstNode nextSibling, T child, Role role) where T : AstNode + public void InsertChildBefore(AstNode? nextSibling, T child, Role role) where T : AstNode { if (role == null) throw new ArgumentNullException(nameof(role)); @@ -469,7 +470,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax nextSibling.prevSibling = child; } - public void InsertChildAfter(AstNode prevSibling, T child, Role role) where T : AstNode + public void InsertChildAfter(AstNode? prevSibling, T child, Role role) where T : AstNode { InsertChildBefore((prevSibling == null || prevSibling.IsNull) ? firstChild : prevSibling.nextSibling, child, role); } @@ -511,7 +512,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// /// Replaces this node with the new node. /// - public void ReplaceWith(AstNode newNode) + public void ReplaceWith(AstNode? newNode) { if (newNode == null || newNode.IsNull) { @@ -578,7 +579,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax nextSibling = null; } - public AstNode ReplaceWith(Func replaceFunction) + public AstNode? ReplaceWith(Func replaceFunction) { if (replaceFunction == null) throw new ArgumentNullException(nameof(replaceFunction)); @@ -587,10 +588,10 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax throw new InvalidOperationException(this.IsNull ? "Cannot replace the null nodes" : "Cannot replace the root node"); } AstNode oldParent = parent; - AstNode oldSuccessor = nextSibling; + AstNode? oldSuccessor = nextSibling; Role oldRole = this.Role; Remove(); - AstNode replacement = replaceFunction(this); + AstNode? replacement = replaceFunction(this); if (oldSuccessor != null && oldSuccessor.parent != oldParent) throw new InvalidOperationException("replace function changed nextSibling of node being replaced?"); if (!(replacement == null || replacement.IsNull)) @@ -626,7 +627,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax copy.flags &= ~frozenBit; // unfreeze the copy // Then perform a deep copy: - for (AstNode cur = firstChild; cur != null; cur = cur.nextSibling) + for (AstNode? cur = firstChild; cur != null; cur = cur.nextSibling) { copy.AddChildUnsafe(cur.Clone(), cur.Role); } @@ -649,37 +650,37 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax public abstract S AcceptVisitor(IAstVisitor visitor, T data); #region Pattern Matching - protected static bool MatchString(string pattern, string text) + protected static bool MatchString(string? pattern, string? text) { return PatternMatching.Pattern.MatchString(pattern, text); } - protected internal abstract bool DoMatch(AstNode other, PatternMatching.Match match); + protected internal abstract bool DoMatch(AstNode? other, PatternMatching.Match match); - bool PatternMatching.INode.DoMatch(PatternMatching.INode other, PatternMatching.Match match) + bool PatternMatching.INode.DoMatch(PatternMatching.INode? other, PatternMatching.Match match) { - AstNode o = other as AstNode; + AstNode? o = other as AstNode; // try matching if other is null, or if other is an AstNode return (other == null || o != null) && DoMatch(o, match); } - bool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo) + bool PatternMatching.INode.DoMatchCollection(Role? role, PatternMatching.INode? pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo? backtrackingInfo) { - AstNode o = pos as AstNode; + AstNode? o = pos as AstNode; return (pos == null || o != null) && DoMatch(o, match); } - PatternMatching.INode PatternMatching.INode.NextSibling { + PatternMatching.INode? PatternMatching.INode.NextSibling { get { return nextSibling; } } - PatternMatching.INode PatternMatching.INode.FirstChild { + PatternMatching.INode? PatternMatching.INode.FirstChild { get { return firstChild; } } #endregion - public AstNode GetNextNode() + public AstNode? GetNextNode() { if (NextSibling != null) return NextSibling; @@ -693,7 +694,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// /// The next node. /// The predicate. - public AstNode GetNextNode(Func pred) + public AstNode? GetNextNode(Func pred) { var next = GetNextNode(); while (next != null && !pred(next)) @@ -701,7 +702,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax return next; } - public AstNode GetPrevNode() + public AstNode? GetPrevNode() { if (PrevSibling != null) return PrevSibling; @@ -715,7 +716,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// /// The next node. /// The predicate. - public AstNode GetPrevNode(Func pred) + public AstNode? GetPrevNode(Func pred) { var prev = GetPrevNode(); while (prev != null && !pred(prev)) @@ -723,7 +724,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax return prev; } // filters all non c# nodes (comments, white spaces or pre processor directives) - public AstNode GetCSharpNodeBefore(AstNode node) + public AstNode? GetCSharpNodeBefore(AstNode node) { var n = node.PrevSibling; while (n != null) @@ -740,7 +741,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// /// The next node. /// The predicate. - public AstNode GetNextSibling(Func pred) + public AstNode? GetNextSibling(Func pred) { var next = NextSibling; while (next != null && !pred(next)) @@ -753,7 +754,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// /// The next node. /// The predicate. - public AstNode GetPrevSibling(Func pred) + public AstNode? GetPrevSibling(Func pred) { var prev = PrevSibling; while (prev != null && !pred(prev)) @@ -767,7 +768,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// the current method declaration. /// (End exclusive) /// - public AstNode GetNodeAt(int line, int column, Predicate pred = null) + public AstNode? GetNodeAt(int line, int column, Predicate? pred = null) { return GetNodeAt(new TextLocation(line, column), pred); } @@ -777,9 +778,9 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// the current method declaration. /// (End exclusive) /// - public AstNode GetNodeAt(TextLocation location, Predicate pred = null) + public AstNode? GetNodeAt(TextLocation location, Predicate? pred = null) { - AstNode result = null; + AstNode? result = null; AstNode node = this; while (node.LastChild != null) { @@ -806,7 +807,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// the current method declaration. /// (End exclusive) /// - public T GetNodeAt(int line, int column) where T : AstNode + public T? GetNodeAt(int line, int column) where T : AstNode { return GetNodeAt(new TextLocation(line, column)); } @@ -816,9 +817,9 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// the current method declaration. /// (End exclusive) /// - public T GetNodeAt(TextLocation location) where T : AstNode + public T? GetNodeAt(TextLocation location) where T : AstNode { - T result = null; + T? result = null; AstNode node = this; while (node.LastChild != null) { @@ -848,7 +849,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// the current method declaration. /// (End inclusive) /// - public AstNode GetAdjacentNodeAt(int line, int column, Predicate pred = null) + public AstNode? GetAdjacentNodeAt(int line, int column, Predicate? pred = null) { return GetAdjacentNodeAt(new TextLocation(line, column), pred); } @@ -858,9 +859,9 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// the current method declaration. /// (End inclusive) /// - public AstNode GetAdjacentNodeAt(TextLocation location, Predicate pred = null) + public AstNode? GetAdjacentNodeAt(TextLocation location, Predicate? pred = null) { - AstNode result = null; + AstNode? result = null; AstNode node = this; while (node.LastChild != null) { @@ -887,7 +888,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// the current method declaration. /// (End inclusive) /// - public T GetAdjacentNodeAt(int line, int column) where T : AstNode + public T? GetAdjacentNodeAt(int line, int column) where T : AstNode { return GetAdjacentNodeAt(new TextLocation(line, column)); } @@ -897,9 +898,9 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// the current method declaration. /// (End inclusive) /// - public T GetAdjacentNodeAt(TextLocation location) where T : AstNode + public T? GetAdjacentNodeAt(TextLocation location) where T : AstNode { - T result = null; + T? result = null; AstNode node = this; while (node.LastChild != null) { @@ -908,8 +909,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax child = child.prevSibling; if (child != null && location <= child.EndLocation) { - if (child is T) - result = (T)child; + if (child is T t) + result = t; node = child; } else @@ -928,7 +929,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// public AstNode GetNodeContaining(TextLocation startLocation, TextLocation endLocation) { - for (AstNode child = firstChild; child != null; child = child.nextSibling) + for (AstNode? child = firstChild; child != null; child = child.nextSibling) { if (child.StartLocation <= startLocation && endLocation <= child.EndLocation) return child.GetNodeContaining(startLocation, endLocation); @@ -949,10 +950,10 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// public IEnumerable GetNodesBetween(TextLocation start, TextLocation end) { - AstNode node = this; + AstNode? node = this; while (node != null) { - AstNode next; + AstNode? next; if (start <= node.StartLocation && node.EndLocation <= end) { // Remember next before yielding node. @@ -984,7 +985,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// /// Formatting options. /// - public virtual string ToString(CSharpFormattingOptions formattingOptions) + public virtual string ToString(CSharpFormattingOptions? formattingOptions) { if (IsNull) return ""; diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/ComposedType.cs b/ICSharpCode.Decompiler/CSharp/Syntax/ComposedType.cs index 05532d89e..c042a2ca9 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/ComposedType.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/ComposedType.cs @@ -41,7 +41,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax public static readonly TokenRole ReadonlyRole = new TokenRole("readonly"); public static readonly TokenRole NullableRole = new TokenRole("?"); public static readonly TokenRole PointerRole = new TokenRole("*"); - public static readonly Role ArraySpecifierRole = new Role("ArraySpecifier"); + public static readonly Role ArraySpecifierRole = new Role("ArraySpecifier", null); public AstNodeCollection Attributes { get { return base.GetChildrenByRole(AttributeRole); } } @@ -299,4 +299,3 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax } } } - diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/Expressions/ArrayCreateExpression.cs b/ICSharpCode.Decompiler/CSharp/Syntax/Expressions/ArrayCreateExpression.cs index eaad6ff6b..e4314f001 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/Expressions/ArrayCreateExpression.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/Expressions/ArrayCreateExpression.cs @@ -25,7 +25,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax public class ArrayCreateExpression : Expression { public readonly static TokenRole NewKeywordRole = new TokenRole("new"); - public readonly static Role AdditionalArraySpecifierRole = new Role("AdditionalArraySpecifier"); + public readonly static Role AdditionalArraySpecifierRole = new Role("AdditionalArraySpecifier", null); public readonly static Role InitializerRole = new Role("Initializer", ArrayInitializerExpression.Null); public CSharpTokenNode NewToken { diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/Expressions/QueryExpression.cs b/ICSharpCode.Decompiler/CSharp/Syntax/Expressions/QueryExpression.cs index 6b91ec02f..87315b01f 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/Expressions/QueryExpression.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/Expressions/QueryExpression.cs @@ -16,13 +16,11 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -using System.Collections.Generic; - namespace ICSharpCode.Decompiler.CSharp.Syntax { public class QueryExpression : Expression { - public static readonly Role ClauseRole = new Role("Clause"); + public static readonly Role ClauseRole = new Role("Clause", null); #region Null public new static readonly QueryExpression Null = new NullQueryExpression(); @@ -420,7 +418,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax public class QueryOrderClause : QueryClause { public static readonly TokenRole OrderbyKeywordRole = new TokenRole("orderby"); - public static readonly Role OrderingRole = new Role("Ordering"); + public static readonly Role OrderingRole = new Role("Ordering", null); public CSharpTokenNode OrderbyToken { get { return GetChildByRole(OrderbyKeywordRole); } @@ -585,4 +583,4 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax return o != null && this.Projection.DoMatch(o.Projection, match) && this.Key.DoMatch(o.Key, match); } } -} \ No newline at end of file +} diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/Expressions/SwitchExpression.cs b/ICSharpCode.Decompiler/CSharp/Syntax/Expressions/SwitchExpression.cs index 9c9e166d6..ca66a0796 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/Expressions/SwitchExpression.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/Expressions/SwitchExpression.cs @@ -25,7 +25,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax public class SwitchExpression : Expression { public static readonly TokenRole SwitchKeywordRole = new TokenRole("switch"); - public static readonly Role SwitchSectionRole = new Role("SwitchSection"); + public static readonly Role SwitchSectionRole = new Role("SwitchSection", null); public Expression Expression { get { return GetChildByRole(Roles.Expression); } diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/PreProcessorDirective.cs b/ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/PreProcessorDirective.cs index 87005c003..a1b175d1c 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/PreProcessorDirective.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/PreProcessorDirective.cs @@ -69,7 +69,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax public class PragmaWarningPreprocessorDirective : PreProcessorDirective { - public static readonly Role WarningRole = new Role("Warning"); + public static readonly Role WarningRole = new Role("Warning", null); public static readonly TokenRole PragmaKeywordRole = new TokenRole("#pragma"); public static readonly TokenRole WarningKeywordRole = new TokenRole("warning"); @@ -200,4 +200,3 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax } } } - diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/Role.cs b/ICSharpCode.Decompiler/CSharp/Syntax/Role.cs index 6d9afb8df..2411a2652 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/Role.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/Role.cs @@ -16,6 +16,8 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#nullable enable + using System; using System.Threading; @@ -64,7 +66,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// Represents the role a node plays within its parent. /// All nodes with this role have type T. /// - public class Role : Role where T : class + public class Role : Role where T : class? { readonly string name; // helps with debugging the AST readonly T nullObject; @@ -86,21 +88,19 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax return node is T; } + [Obsolete("Use the other overload explicitly specifying the nullObject.")] public Role(string name) { if (name == null) throw new ArgumentNullException(nameof(name)); this.name = name; + this.nullObject = null!; } public Role(string name, T nullObject) { - if (name == null) - throw new ArgumentNullException(nameof(name)); - if (nullObject == null) - throw new ArgumentNullException(nameof(nullObject)); + this.name = name ?? throw new ArgumentNullException(nameof(name)); this.nullObject = nullObject; - this.name = name; } public override string ToString() diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/Roles.cs b/ICSharpCode.Decompiler/CSharp/Syntax/Roles.cs index 10c9ab72c..f55c63542 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/Roles.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/Roles.cs @@ -34,18 +34,18 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax // some pre defined constants for common roles public static readonly Role Identifier = new Role("Identifier", Syntax.Identifier.Null); public static readonly Role Body = new Role("Body", BlockStatement.Null); - public static readonly Role Parameter = new Role("Parameter"); + public static readonly Role Parameter = new Role("Parameter", null); public static readonly Role Argument = new Role("Argument", Syntax.Expression.Null); public static readonly Role Type = new Role("Type", AstType.Null); public static readonly Role Expression = new Role("Expression", Syntax.Expression.Null); public static readonly Role TargetExpression = new Role("Target", Syntax.Expression.Null); public readonly static Role Condition = new Role("Condition", Syntax.Expression.Null); - public static readonly Role TypeParameter = new Role("TypeParameter"); + public static readonly Role TypeParameter = new Role("TypeParameter", null); public static readonly Role TypeArgument = new Role("TypeArgument", AstType.Null); - public readonly static Role Constraint = new Role("Constraint"); + public readonly static Role Constraint = new Role("Constraint", null); public static readonly Role Variable = new Role("Variable", VariableInitializer.Null); public static readonly Role EmbeddedStatement = new Role("EmbeddedStatement", Statement.Null); - public readonly static Role TypeMemberRole = new Role("TypeMember"); + public readonly static Role TypeMemberRole = new Role("TypeMember", null); public static readonly Role VariableDesignationRole = new Role("VariableDesignation", VariableDesignation.Null); @@ -68,12 +68,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax public static readonly TokenRole Colon = new TokenRole(":"); public static readonly TokenRole DoubleColon = new TokenRole("::"); public static readonly TokenRole Arrow = new TokenRole("=>"); - public static readonly Role Comment = new Role("Comment"); - public static readonly Role PreProcessorDirective = new Role("PreProcessorDirective"); + public static readonly Role Comment = new Role("Comment", null); + public static readonly Role PreProcessorDirective = new Role("PreProcessorDirective", null); public readonly static Role BaseType = new Role("BaseType", AstType.Null); - public static readonly Role Attribute = new Role("Attribute"); + public static readonly Role Attribute = new Role("Attribute", null); public static readonly Role AttributeTargetRole = new Role("AttributeTarget", CSharpTokenNode.Null); public readonly static TokenRole WhereKeyword = new TokenRole("where"); diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/Statements/LocalFunctionDeclarationStatement.cs b/ICSharpCode.Decompiler/CSharp/Syntax/Statements/LocalFunctionDeclarationStatement.cs index 105789bb3..da2d1550f 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/Statements/LocalFunctionDeclarationStatement.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/Statements/LocalFunctionDeclarationStatement.cs @@ -22,7 +22,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax { public class LocalFunctionDeclarationStatement : Statement { - public static readonly Role MethodDeclarationRole = new Role("Method"); + public static readonly Role MethodDeclarationRole = new Role("Method", null); public MethodDeclaration Declaration { get { return GetChildByRole(MethodDeclarationRole); } diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/Statements/SwitchStatement.cs b/ICSharpCode.Decompiler/CSharp/Syntax/Statements/SwitchStatement.cs index c6f3c5745..a3412d1c8 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/Statements/SwitchStatement.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/Statements/SwitchStatement.cs @@ -33,7 +33,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax public class SwitchStatement : Statement { public static readonly TokenRole SwitchKeywordRole = new TokenRole("switch"); - public static readonly Role SwitchSectionRole = new Role("SwitchSection"); + public static readonly Role SwitchSectionRole = new Role("SwitchSection", null); public CSharpTokenNode SwitchToken { get { return GetChildByRole(SwitchKeywordRole); } @@ -134,7 +134,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax } #endregion - public static readonly Role CaseLabelRole = new Role("CaseLabel"); + public static readonly Role CaseLabelRole = new Role("CaseLabel", null); public override NodeType NodeType { get { diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/EntityDeclaration.cs b/ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/EntityDeclaration.cs index d040f0483..28cfb0798 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/EntityDeclaration.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/EntityDeclaration.cs @@ -25,8 +25,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax { public abstract class EntityDeclaration : AstNode { - public static readonly Role AttributeRole = new Role("Attribute"); - public static readonly Role ModifierRole = new Role("Modifier"); + public static readonly Role AttributeRole = new Role("Attribute", null); + public static readonly Role ModifierRole = new Role("Modifier", null); public static readonly Role PrivateImplementationTypeRole = new Role("PrivateImplementationType", AstType.Null); public override NodeType NodeType { diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/FixedFieldDeclaration.cs b/ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/FixedFieldDeclaration.cs index 32e8a7512..2d31d86ab 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/FixedFieldDeclaration.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/FixedFieldDeclaration.cs @@ -30,7 +30,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax public class FixedFieldDeclaration : EntityDeclaration { public static readonly TokenRole FixedKeywordRole = new TokenRole("fixed"); - public static readonly Role VariableRole = new Role("FixedVariable"); + public static readonly Role VariableRole = new Role("FixedVariable", null); public override SymbolKind SymbolKind { get { return SymbolKind.Field; } @@ -67,4 +67,3 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax } } } -