Browse Source

#nullable enable for most files in ICSharpCode.Decompiler/Util

issue1638
Daniel Grunwald 4 years ago
parent
commit
b9eee606af
  1. 1
      ICSharpCode.Decompiler/Util/BitSet.cs
  2. 13
      ICSharpCode.Decompiler/Util/BusyManager.cs
  3. 6
      ICSharpCode.Decompiler/Util/CSharpPrimitiveCast.cs
  4. 2
      ICSharpCode.Decompiler/Util/CacheManager.cs
  5. 6
      ICSharpCode.Decompiler/Util/CallbackOnDispose.cs
  6. 35
      ICSharpCode.Decompiler/Util/CollectionExtensions.cs
  7. 5
      ICSharpCode.Decompiler/Util/EmptyList.cs
  8. 5
      ICSharpCode.Decompiler/Util/ExtensionMethods.cs
  9. 24
      ICSharpCode.Decompiler/Util/FileUtility.cs
  10. 26
      ICSharpCode.Decompiler/Util/GraphVizGraph.cs
  11. 7
      ICSharpCode.Decompiler/Util/Interval.cs
  12. 3
      ICSharpCode.Decompiler/Util/KeyComparer.cs
  13. 7
      ICSharpCode.Decompiler/Util/LongSet.cs
  14. 5
      ICSharpCode.Decompiler/Util/MultiDictionary.cs
  15. 3
      ICSharpCode.Decompiler/Util/Platform.cs
  16. 15
      ICSharpCode.Decompiler/Util/ProjectedList.cs
  17. 7
      ICSharpCode.Decompiler/Util/ReferenceComparer.cs
  18. 27
      ICSharpCode.Decompiler/Util/ResourcesFile.cs
  19. 15
      ICSharpCode.Decompiler/Util/TreeTraversal.cs
  20. 7
      ICSharpCode.Decompiler/Util/UnicodeNewline.cs
  21. 14
      ICSharpCode.Decompiler/Util/UnionFind.cs
  22. 23
      ICSharpCode.Decompiler/Util/Win32Resources.cs
  23. 4
      ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj

1
ICSharpCode.Decompiler/Util/BitSet.cs

@ -15,6 +15,7 @@
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // 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 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
#nullable enable
using System; using System;
using System.Diagnostics; using System.Diagnostics;

13
ICSharpCode.Decompiler/Util/BusyManager.cs

@ -15,6 +15,7 @@
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // 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 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -36,9 +37,9 @@ namespace ICSharpCode.Decompiler.Util
{ {
public static readonly BusyLock Failed = new BusyLock(null); public static readonly BusyLock Failed = new BusyLock(null);
readonly List<object> objectList; readonly List<object?>? objectList;
internal BusyLock(List<object> objectList) internal BusyLock(List<object?>? objectList)
{ {
this.objectList = objectList; this.objectList = objectList;
} }
@ -56,13 +57,13 @@ namespace ICSharpCode.Decompiler.Util
} }
} }
[ThreadStatic] static List<object> _activeObjects; [ThreadStatic] static List<object?>? _activeObjects;
public static BusyLock Enter(object obj) public static BusyLock Enter(object? obj)
{ {
List<object> activeObjects = _activeObjects; List<object?>? activeObjects = _activeObjects;
if (activeObjects == null) if (activeObjects == null)
activeObjects = _activeObjects = new List<object>(); activeObjects = _activeObjects = new List<object?>();
for (int i = 0; i < activeObjects.Count; i++) for (int i = 0; i < activeObjects.Count; i++)
{ {
if (activeObjects[i] == obj) if (activeObjects[i] == obj)

6
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 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
#nullable enable
using System; using System;
using System.Diagnostics.CodeAnalysis;
namespace ICSharpCode.Decompiler.Util namespace ICSharpCode.Decompiler.Util
{ {
@ -34,7 +37,8 @@ namespace ICSharpCode.Decompiler.Util
/// </summary> /// </summary>
/// <exception cref="OverflowException">Overflow checking is enabled and an overflow occurred.</exception> /// <exception cref="OverflowException">Overflow checking is enabled and an overflow occurred.</exception>
/// <exception cref="InvalidCastException">The cast is invalid, e.g. casting a boolean to an integer.</exception> /// <exception cref="InvalidCastException">The cast is invalid, e.g. casting a boolean to an integer.</exception>
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) if (input == null)
return null; return null;

2
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 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
#nullable enable
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;

6
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 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
#nullable enable
using System; using System;
using System.Threading; using System.Threading;
@ -30,7 +32,7 @@ namespace ICSharpCode.Decompiler.Util
/// </remarks> /// </remarks>
public sealed class CallbackOnDispose : IDisposable public sealed class CallbackOnDispose : IDisposable
{ {
Action action; Action? action;
public CallbackOnDispose(Action action) public CallbackOnDispose(Action action)
{ {
@ -41,7 +43,7 @@ namespace ICSharpCode.Decompiler.Util
public void Dispose() public void Dispose()
{ {
Action a = Interlocked.Exchange(ref action, null); Action? a = Interlocked.Exchange(ref action, null);
if (a != null) if (a != null)
{ {
a(); a();

35
ICSharpCode.Decompiler/Util/CollectionExtensions.cs

@ -1,4 +1,5 @@
using System; #nullable enable
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
@ -14,13 +15,13 @@ namespace ICSharpCode.Decompiler.Util
} }
#if !NETCORE #if !NETCORE
public static IEnumerable<(A, B)> Zip<A, B>(this IEnumerable<A> input1, IEnumerable<B> input2) public static IEnumerable<(A, B)> Zip<A, B>(this IEnumerable<A>? input1, IEnumerable<B>? input2)
{ {
return input1.Zip(input2, (a, b) => (a, b)); return input1.Zip(input2, (a, b) => (a, b));
} }
#endif #endif
public static IEnumerable<(A, B)> ZipLongest<A, B>(this IEnumerable<A> input1, IEnumerable<B> input2) public static IEnumerable<(A?, B?)> ZipLongest<A, B>(this IEnumerable<A> input1, IEnumerable<B> input2)
{ {
using (var it1 = input1.GetEnumerator()) using (var it1 = input1.GetEnumerator())
{ {
@ -60,7 +61,7 @@ namespace ICSharpCode.Decompiler.Util
} }
#if !NETCORE #if !NETCORE
public static HashSet<T> ToHashSet<T>(this IEnumerable<T> input) public static HashSet<T> ToHashSet<T>(this IEnumerable<T>? input)
{ {
return new HashSet<T>(input); return new HashSet<T>(input);
} }
@ -76,14 +77,14 @@ namespace ICSharpCode.Decompiler.Util
return input.Skip(input.Count - count); return input.Skip(input.Count - count);
} }
public static T PopOrDefault<T>(this Stack<T> stack) public static T? PopOrDefault<T>(this Stack<T> stack)
{ {
if (stack.Count == 0) if (stack.Count == 0)
return default(T); return default(T);
return stack.Pop(); return stack.Pop();
} }
public static T PeekOrDefault<T>(this Stack<T> stack) public static T? PeekOrDefault<T>(this Stack<T> stack)
{ {
if (stack.Count == 0) if (stack.Count == 0)
return default(T); return default(T);
@ -277,7 +278,7 @@ namespace ICSharpCode.Decompiler.Util
/// Returns the minimum element. /// Returns the minimum element.
/// </summary> /// </summary>
/// <exception cref="InvalidOperationException">The input sequence is empty</exception> /// <exception cref="InvalidOperationException">The input sequence is empty</exception>
public static T MinBy<T, K>(this IEnumerable<T> source, Func<T, K> keySelector, IComparer<K> keyComparer) public static T MinBy<T, K>(this IEnumerable<T> source, Func<T, K> keySelector, IComparer<K>? keyComparer)
{ {
if (source == null) if (source == null)
throw new ArgumentNullException(nameof(source)); throw new ArgumentNullException(nameof(source));
@ -318,7 +319,7 @@ namespace ICSharpCode.Decompiler.Util
/// Returns the maximum element. /// Returns the maximum element.
/// </summary> /// </summary>
/// <exception cref="InvalidOperationException">The input sequence is empty</exception> /// <exception cref="InvalidOperationException">The input sequence is empty</exception>
public static T MaxBy<T, K>(this IEnumerable<T> source, Func<T, K> keySelector, IComparer<K> keyComparer) public static T MaxBy<T, K>(this IEnumerable<T> source, Func<T, K> keySelector, IComparer<K>? keyComparer)
{ {
if (source == null) if (source == null)
throw new ArgumentNullException(nameof(source)); throw new ArgumentNullException(nameof(source));
@ -353,12 +354,12 @@ namespace ICSharpCode.Decompiler.Util
list.RemoveAt(list.Count - 1); list.RemoveAt(list.Count - 1);
} }
public static T OnlyOrDefault<T>(this IEnumerable<T> source, Func<T, bool> predicate) => OnlyOrDefault(source.Where(predicate)); public static T? OnlyOrDefault<T>(this IEnumerable<T>? source, Func<T, bool>? predicate) => OnlyOrDefault(source.Where(predicate));
public static T OnlyOrDefault<T>(this IEnumerable<T> source) public static T? OnlyOrDefault<T>(this IEnumerable<T> source)
{ {
bool any = false; bool any = false;
T first = default; T? first = default;
foreach (var t in source) foreach (var t in source)
{ {
if (any) if (any)
@ -372,14 +373,14 @@ namespace ICSharpCode.Decompiler.Util
#region Aliases/shortcuts for Enumerable extension methods #region Aliases/shortcuts for Enumerable extension methods
public static bool Any<T>(this ICollection<T> list) => list.Count > 0; public static bool Any<T>(this ICollection<T> list) => list.Count > 0;
public static bool Any<T>(this T[] array, Predicate<T> match) => Array.Exists(array, match); public static bool Any<T>(this T[]? array, Predicate<T>? match) => Array.Exists(array, match);
public static bool Any<T>(this List<T> list, Predicate<T> match) => list.Exists(match); public static bool Any<T>(this List<T> list, Predicate<T>? match) => list.Exists(match);
public static bool All<T>(this T[] array, Predicate<T> match) => Array.TrueForAll(array, match); public static bool All<T>(this T[]? array, Predicate<T>? match) => Array.TrueForAll(array, match);
public static bool All<T>(this List<T> list, Predicate<T> match) => list.TrueForAll(match); public static bool All<T>(this List<T> list, Predicate<T>? match) => list.TrueForAll(match);
public static T FirstOrDefault<T>(this T[] array, Predicate<T> predicate) => Array.Find(array, predicate); public static T FirstOrDefault<T>(this T[]? array, Predicate<T>? predicate) => Array.Find(array, predicate);
public static T FirstOrDefault<T>(this List<T> list, Predicate<T> predicate) => list.Find(predicate); public static T FirstOrDefault<T>(this List<T> list, Predicate<T>? predicate) => list.Find(predicate);
public static T Last<T>(this IList<T> list) => list[list.Count - 1]; public static T Last<T>(this IList<T> list) => list[list.Count - 1];
#endregion #endregion

5
ICSharpCode.Decompiler/Util/EmptyList.cs

@ -15,6 +15,7 @@
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // 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 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
#nullable enable
using System; using System;
using System.Collections; using System.Collections;
@ -91,11 +92,11 @@ namespace ICSharpCode.Decompiler.Util
} }
T IEnumerator<T>.Current { T IEnumerator<T>.Current {
get { return default(T); } get { throw new NotSupportedException(); }
} }
object IEnumerator.Current { object IEnumerator.Current {
get { return default(T); } get { throw new NotSupportedException(); }
} }
void IDisposable.Dispose() void IDisposable.Dispose()

5
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 // 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 // software and associated documentation files (the "Software"), to deal in the Software
@ -26,7 +27,7 @@ namespace ICSharpCode.Decompiler.Util
/// </summary> /// </summary>
static class ExtensionMethods static class ExtensionMethods
{ {
public static Predicate<T> And<T>(this Predicate<T> filter1, Predicate<T> filter2) public static Predicate<T>? And<T>(this Predicate<T>? filter1, Predicate<T>? filter2)
{ {
if (filter1 == null) if (filter1 == null)
return filter2; return filter2;

24
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 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
#nullable enable
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Text; using System.Text;
@ -28,9 +31,10 @@ namespace ICSharpCode.Decompiler.Util
/// Gets the normalized version of fileName. /// Gets the normalized version of fileName.
/// Slashes are replaced with backslashes, backreferences "." and ".." are 'evaluated'. /// Slashes are replaced with backslashes, backreferences "." and ".." are 'evaluated'.
/// </summary> /// </summary>
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; return fileName;
int i; int i;
@ -169,14 +173,14 @@ namespace ICSharpCode.Decompiler.Util
&& (fileName[1] == '\\' || fileName[1] == '/'); && (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), return string.Equals(NormalizePath(fileName1),
NormalizePath(fileName2), NormalizePath(fileName2),
StringComparison.OrdinalIgnoreCase); StringComparison.OrdinalIgnoreCase);
} }
public static bool IsBaseDirectory(string baseDirectory, string testDirectory) public static bool IsBaseDirectory(string? baseDirectory, string? testDirectory)
{ {
if (baseDirectory == null || testDirectory == null) if (baseDirectory == null || testDirectory == null)
return false; return false;
@ -189,9 +193,10 @@ namespace ICSharpCode.Decompiler.Util
return testDirectory.StartsWith(baseDirectory, StringComparison.OrdinalIgnoreCase); 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; return input;
if (input[input.Length - 1] == Path.DirectorySeparatorChar || input[input.Length - 1] == Path.AltDirectorySeparatorChar) if (input[input.Length - 1] == Path.DirectorySeparatorChar || input[input.Length - 1] == Path.AltDirectorySeparatorChar)
return input; 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 /// 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) /// from the base path to the absoulte path. (as a relative path)
/// </summary> /// </summary>
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; return absPath;
} }
@ -252,7 +257,8 @@ namespace ICSharpCode.Decompiler.Util
return erg.ToString(); 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 char ellipsis = '\u2026'; // HORIZONTAL ELLIPSIS
const int ellipsisLength = 2; const int ellipsisLength = 2;

26
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 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
@ -34,8 +36,8 @@ namespace ICSharpCode.Decompiler.Util
List<GraphVizNode> nodes = new List<GraphVizNode>(); List<GraphVizNode> nodes = new List<GraphVizNode>();
List<GraphVizEdge> edges = new List<GraphVizEdge>(); List<GraphVizEdge> edges = new List<GraphVizEdge>();
public string rankdir; public string? rankdir;
public string Title; public string? Title;
public void AddEdge(GraphVizEdge edge) public void AddEdge(GraphVizEdge edge)
{ {
@ -58,7 +60,7 @@ namespace ICSharpCode.Decompiler.Util
Show(null); Show(null);
} }
public void Show(string name) public void Show(string? name)
{ {
if (name == null) if (name == null)
name = Title; 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) if (value != null)
writer.WriteLine("{0}={1};", name, Escape(value)); 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) if (value != null)
{ {
@ -141,13 +143,13 @@ namespace ICSharpCode.Decompiler.Util
public readonly string Source, Target; public readonly string Source, Target;
/// <summary>edge stroke color</summary> /// <summary>edge stroke color</summary>
public string color; public string? color;
/// <summary>use edge to affect node ranking</summary> /// <summary>use edge to affect node ranking</summary>
public bool? constraint; public bool? constraint;
public string label; public string? label;
public string style; public string? style;
/// <summary>point size of label</summary> /// <summary>point size of label</summary>
public int? fontsize; public int? fontsize;
@ -184,9 +186,9 @@ namespace ICSharpCode.Decompiler.Util
sealed class GraphVizNode sealed class GraphVizNode
{ {
public readonly string ID; public readonly string ID;
public string label; public string? label;
public string labelloc; public string? labelloc;
/// <summary>point size of label</summary> /// <summary>point size of label</summary>
public int? fontsize; public int? fontsize;
@ -195,10 +197,10 @@ namespace ICSharpCode.Decompiler.Util
public double? height; public double? height;
/// <summary>space around label</summary> /// <summary>space around label</summary>
public string margin; public string? margin;
/// <summary>node shape</summary> /// <summary>node shape</summary>
public string shape; public string? shape;
public GraphVizNode(string id) public GraphVizNode(string id)
{ {

7
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 // 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 // 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 #region Equals and GetHashCode implementation
public override bool Equals(object obj) public override bool Equals(object? obj)
{ {
return (obj is Interval) && Equals((Interval)obj); return (obj is Interval) && Equals((Interval)obj);
} }
@ -281,7 +282,7 @@ namespace ICSharpCode.Decompiler.Util
} }
#region Equals and GetHashCode implementation #region Equals and GetHashCode implementation
public override bool Equals(object obj) public override bool Equals(object? obj)
{ {
return (obj is LongInterval) && Equals((LongInterval)obj); return (obj is LongInterval) && Equals((LongInterval)obj);
} }

3
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 // 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 // software and associated documentation files (the "Software"), to deal in the Software

7
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 // 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 // software and associated documentation files (the "Software"), to deal in the Software
@ -82,7 +83,7 @@ namespace ICSharpCode.Decompiler.Util
/// <summary> /// <summary>
/// Creates a new LongSet the contains the values from the specified intervals. /// Creates a new LongSet the contains the values from the specified intervals.
/// </summary> /// </summary>
public LongSet(IEnumerable<LongInterval> intervals) public LongSet(IEnumerable<LongInterval>? intervals)
: this(MergeOverlapping(intervals.Where(i => !i.IsEmpty).OrderBy(i => i.Start)).ToImmutableArray()) : 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 #region Equals and GetHashCode implementation
public override bool Equals(object obj) public override bool Equals(object? obj)
{ {
return obj is LongSet && SetEquals((LongSet)obj); return obj is LongSet && SetEquals((LongSet)obj);
} }

5
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 // 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 // software and associated documentation files (the "Software"), to deal in the Software
@ -33,7 +34,7 @@ namespace ICSharpCode.Decompiler.Util
dict = new Dictionary<TKey, List<TValue>>(); dict = new Dictionary<TKey, List<TValue>>();
} }
public MultiDictionary(IEqualityComparer<TKey> comparer) public MultiDictionary(IEqualityComparer<TKey>? comparer)
{ {
dict = new Dictionary<TKey, List<TValue>>(comparer); dict = new Dictionary<TKey, List<TValue>>(comparer);
} }

3
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 // 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 // software and associated documentation files (the "Software"), to deal in the Software

15
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 // 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 // software and associated documentation files (the "Software"), to deal in the Software
@ -25,7 +26,7 @@ namespace ICSharpCode.Decompiler.Util
{ {
readonly IList<TInput> input; readonly IList<TInput> input;
readonly Func<TInput, TOutput> projection; readonly Func<TInput, TOutput> projection;
readonly TOutput[] items; readonly TOutput?[] items;
public ProjectedList(IList<TInput> input, Func<TInput, TOutput> projection) public ProjectedList(IList<TInput> input, Func<TInput, TOutput> projection)
{ {
@ -35,12 +36,12 @@ namespace ICSharpCode.Decompiler.Util
throw new ArgumentNullException(nameof(projection)); throw new ArgumentNullException(nameof(projection));
this.input = input; this.input = input;
this.projection = projection; this.projection = projection;
this.items = new TOutput[input.Count]; this.items = new TOutput?[input.Count];
} }
public TOutput this[int index] { public TOutput this[int index] {
get { get {
TOutput output = LazyInit.VolatileRead(ref items[index]); TOutput? output = LazyInit.VolatileRead(ref items[index]);
if (output != null) if (output != null)
{ {
return output; return output;
@ -72,7 +73,7 @@ namespace ICSharpCode.Decompiler.Util
readonly IList<TInput> input; readonly IList<TInput> input;
readonly TContext context; readonly TContext context;
readonly Func<TContext, TInput, TOutput> projection; readonly Func<TContext, TInput, TOutput> projection;
readonly TOutput[] items; readonly TOutput?[] items;
public ProjectedList(TContext context, IList<TInput> input, Func<TContext, TInput, TOutput> projection) public ProjectedList(TContext context, IList<TInput> input, Func<TContext, TInput, TOutput> projection)
{ {
@ -83,12 +84,12 @@ namespace ICSharpCode.Decompiler.Util
this.input = input; this.input = input;
this.context = context; this.context = context;
this.projection = projection; this.projection = projection;
this.items = new TOutput[input.Count]; this.items = new TOutput?[input.Count];
} }
public TOutput this[int index] { public TOutput this[int index] {
get { get {
TOutput output = LazyInit.VolatileRead(ref items[index]); TOutput? output = LazyInit.VolatileRead(ref items[index]);
if (output != null) if (output != null)
{ {
return output; return output;

7
ICSharpCode.Decompiler/Util/ReferenceComparer.cs

@ -15,22 +15,23 @@
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // 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 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
#nullable enable
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace ICSharpCode.Decompiler.Util namespace ICSharpCode.Decompiler.Util
{ {
public sealed class ReferenceComparer : IEqualityComparer<object> public sealed class ReferenceComparer : IEqualityComparer<object?>
{ {
public readonly static ReferenceComparer Instance = new ReferenceComparer(); 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; return x == y;
} }
public int GetHashCode(object obj) public int GetHashCode(object? obj)
{ {
return RuntimeHelpers.GetHashCode(obj); return RuntimeHelpers.GetHashCode(obj);
} }

27
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 // Based on the .NET Core ResourceReader; make available under the MIT license
// by the .NET Foundation. // by the .NET Foundation.
// //
@ -30,7 +31,7 @@ namespace ICSharpCode.Decompiler.Util
/// <summary> /// <summary>
/// .resources file. /// .resources file.
/// </summary> /// </summary>
public class ResourcesFile : IEnumerable<KeyValuePair<string, object>>, IDisposable public class ResourcesFile : IEnumerable<KeyValuePair<string, object?>>, IDisposable
{ {
sealed class MyBinaryReader : BinaryReader sealed class MyBinaryReader : BinaryReader
{ {
@ -87,7 +88,7 @@ namespace ICSharpCode.Decompiler.Util
readonly long fileStartPosition; readonly long fileStartPosition;
readonly long nameSectionPosition; readonly long nameSectionPosition;
readonly long dataSectionPosition; readonly long dataSectionPosition;
long[] startPositions; long[]? startPositions;
/// <summary> /// <summary>
/// Creates a new ResourcesFile. /// Creates a new ResourcesFile.
@ -285,7 +286,7 @@ namespace ICSharpCode.Decompiler.Util
return true; return true;
} }
object LoadObject(int dataOffset) object? LoadObject(int dataOffset)
{ {
try try
{ {
@ -318,7 +319,7 @@ namespace ICSharpCode.Decompiler.Util
// from that location. // from that location.
// Anyone who calls LoadObject should make sure they take a lock so // Anyone who calls LoadObject should make sure they take a lock so
// no one can cause us to do a seek in here. // 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)); Debug.Assert(System.Threading.Monitor.IsEntered(reader));
reader.Seek(dataSectionPosition + dataOffset, SeekOrigin.Begin); 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)); Debug.Assert(System.Threading.Monitor.IsEntered(reader));
reader.Seek(dataSectionPosition + dataOffset, SeekOrigin.Begin); 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); GetResourceName(index, out int dataOffset);
return LoadObject(dataOffset); return LoadObject(dataOffset);
} }
public IEnumerator<KeyValuePair<string, object>> GetEnumerator() public IEnumerator<KeyValuePair<string, object?>> GetEnumerator()
{ {
for (int i = 0; i < numResources; i++) for (int i = 0; i < numResources; i++)
{ {
string name = GetResourceName(i, out int dataOffset); string name = GetResourceName(i, out int dataOffset);
object val = LoadObject(dataOffset); object? val = LoadObject(dataOffset);
yield return new KeyValuePair<string, object>(name, val); yield return new KeyValuePair<string, object?>(name, val);
} }
} }
@ -487,7 +488,7 @@ namespace ICSharpCode.Decompiler.Util
long[] GetStartPositions() long[] GetStartPositions()
{ {
long[] positions = LazyInit.VolatileRead(ref startPositions); long[]? positions = LazyInit.VolatileRead(ref startPositions);
if (positions != null) if (positions != null)
return positions; return positions;
lock (reader) lock (reader)
@ -541,11 +542,11 @@ namespace ICSharpCode.Decompiler.Util
public class ResourceSerializedObject public class ResourceSerializedObject
{ {
public string TypeName { get; } public string? TypeName { get; }
readonly ResourcesFile file; readonly ResourcesFile file;
readonly long position; readonly long position;
internal ResourceSerializedObject(string typeName, ResourcesFile file, long position) internal ResourceSerializedObject(string? typeName, ResourcesFile file, long position)
{ {
this.TypeName = typeName; this.TypeName = typeName;
this.file = file; this.file = file;

15
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 // 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 // software and associated documentation files (the "Software"), to deal in the Software
@ -32,7 +33,7 @@ namespace ICSharpCode.Decompiler.Util
/// <param name="root">The root element of the tree.</param> /// <param name="root">The root element of the tree.</param>
/// <param name="recursion">The function that gets the children of an element.</param> /// <param name="recursion">The function that gets the children of an element.</param>
/// <returns>Iterator that enumerates the tree structure in pre-order.</returns> /// <returns>Iterator that enumerates the tree structure in pre-order.</returns>
public static IEnumerable<T> PreOrder<T>(T root, Func<T, IEnumerable<T>> recursion) public static IEnumerable<T> PreOrder<T>(T root, Func<T, IEnumerable<T>?> recursion)
{ {
return PreOrder(new T[] { root }, recursion); return PreOrder(new T[] { root }, recursion);
} }
@ -43,7 +44,7 @@ namespace ICSharpCode.Decompiler.Util
/// <param name="input">The root elements of the forest.</param> /// <param name="input">The root elements of the forest.</param>
/// <param name="recursion">The function that gets the children of an element.</param> /// <param name="recursion">The function that gets the children of an element.</param>
/// <returns>Iterator that enumerates the tree structure in pre-order.</returns> /// <returns>Iterator that enumerates the tree structure in pre-order.</returns>
public static IEnumerable<T> PreOrder<T>(IEnumerable<T> input, Func<T, IEnumerable<T>> recursion) public static IEnumerable<T> PreOrder<T>(IEnumerable<T> input, Func<T, IEnumerable<T>?> recursion)
{ {
Stack<IEnumerator<T>> stack = new Stack<IEnumerator<T>>(); Stack<IEnumerator<T>> stack = new Stack<IEnumerator<T>>();
try try
@ -55,7 +56,7 @@ namespace ICSharpCode.Decompiler.Util
{ {
T element = stack.Peek().Current; T element = stack.Peek().Current;
yield return element; yield return element;
IEnumerable<T> children = recursion(element); IEnumerable<T>? children = recursion(element);
if (children != null) if (children != null)
{ {
stack.Push(children.GetEnumerator()); stack.Push(children.GetEnumerator());
@ -79,7 +80,7 @@ namespace ICSharpCode.Decompiler.Util
/// <param name="root">The root element of the tree.</param> /// <param name="root">The root element of the tree.</param>
/// <param name="recursion">The function that gets the children of an element.</param> /// <param name="recursion">The function that gets the children of an element.</param>
/// <returns>Iterator that enumerates the tree structure in post-order.</returns> /// <returns>Iterator that enumerates the tree structure in post-order.</returns>
public static IEnumerable<T> PostOrder<T>(T root, Func<T, IEnumerable<T>> recursion) public static IEnumerable<T> PostOrder<T>(T root, Func<T, IEnumerable<T>?> recursion)
{ {
return PostOrder(new T[] { root }, recursion); return PostOrder(new T[] { root }, recursion);
} }
@ -90,7 +91,7 @@ namespace ICSharpCode.Decompiler.Util
/// <param name="input">The root elements of the forest.</param> /// <param name="input">The root elements of the forest.</param>
/// <param name="recursion">The function that gets the children of an element.</param> /// <param name="recursion">The function that gets the children of an element.</param>
/// <returns>Iterator that enumerates the tree structure in post-order.</returns> /// <returns>Iterator that enumerates the tree structure in post-order.</returns>
public static IEnumerable<T> PostOrder<T>(IEnumerable<T> input, Func<T, IEnumerable<T>> recursion) public static IEnumerable<T> PostOrder<T>(IEnumerable<T> input, Func<T, IEnumerable<T>?> recursion)
{ {
Stack<IEnumerator<T>> stack = new Stack<IEnumerator<T>>(); Stack<IEnumerator<T>> stack = new Stack<IEnumerator<T>>();
try try
@ -101,7 +102,7 @@ namespace ICSharpCode.Decompiler.Util
while (stack.Peek().MoveNext()) while (stack.Peek().MoveNext())
{ {
T element = stack.Peek().Current; T element = stack.Peek().Current;
IEnumerable<T> children = recursion(element); IEnumerable<T>? children = recursion(element);
if (children != null) if (children != null)
{ {
stack.Push(children.GetEnumerator()); stack.Push(children.GetEnumerator());

7
ICSharpCode.Decompiler/Util/UnicodeNewline.cs

@ -1,3 +1,4 @@
#nullable enable
// //
// UnicodeNewline.cs // UnicodeNewline.cs
// //
@ -118,7 +119,7 @@ namespace ICSharpCode.Decompiler.Util
/// <returns>0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter.</returns> /// <returns>0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter.</returns>
/// <param name="curChar">The current character.</param> /// <param name="curChar">The current character.</param>
/// <param name="nextChar">A callback getting the next character (may be null).</param> /// <param name="nextChar">A callback getting the next character (may be null).</param>
public static int GetDelimiterLength(char curChar, Func<char> nextChar = null) public static int GetDelimiterLength(char curChar, Func<char>? nextChar = null)
{ {
if (curChar == CR) if (curChar == CR)
{ {
@ -161,7 +162,7 @@ namespace ICSharpCode.Decompiler.Util
/// <param name = "length">The length of the delimiter</param> /// <param name = "length">The length of the delimiter</param>
/// <param name = "type">The type of the delimiter</param> /// <param name = "type">The type of the delimiter</param>
/// <param name="nextChar">A callback getting the next character (may be null).</param> /// <param name="nextChar">A callback getting the next character (may be null).</param>
public static bool TryGetDelimiterLengthAndType(char curChar, out int length, out UnicodeNewline type, Func<char> nextChar = null) public static bool TryGetDelimiterLengthAndType(char curChar, out int length, out UnicodeNewline type, Func<char>? nextChar = null)
{ {
if (curChar == CR) if (curChar == CR)
{ {
@ -275,7 +276,7 @@ namespace ICSharpCode.Decompiler.Util
/// <returns>0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter.</returns> /// <returns>0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter.</returns>
/// <param name="curChar">The current character.</param> /// <param name="curChar">The current character.</param>
/// <param name="nextChar">A callback getting the next character (may be null).</param> /// <param name="nextChar">A callback getting the next character (may be null).</param>
public static UnicodeNewline GetDelimiterType(char curChar, Func<char> nextChar = null) public static UnicodeNewline GetDelimiterType(char curChar, Func<char>? nextChar = null)
{ {
switch (curChar) switch (curChar)
{ {

14
ICSharpCode.Decompiler/Util/UnionFind.cs

@ -15,6 +15,7 @@
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // 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 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
#nullable enable
using System.Collections.Generic; using System.Collections.Generic;
@ -32,6 +33,12 @@ namespace ICSharpCode.Decompiler.Util
public int rank; public int rank;
public Node parent; public Node parent;
public T value; public T value;
internal Node(T value)
{
this.value = value;
this.parent = this;
}
} }
public UnionFind() public UnionFind()
@ -44,10 +51,7 @@ namespace ICSharpCode.Decompiler.Util
Node node; Node node;
if (!mapping.TryGetValue(element, out node)) if (!mapping.TryGetValue(element, out node))
{ {
node = new Node { node = new Node(element);
value = element,
rank = 0
};
node.parent = node; node.parent = node;
mapping.Add(element, node); mapping.Add(element, node);
} }
@ -84,5 +88,3 @@ namespace ICSharpCode.Decompiler.Util
} }
} }
} }

23
ICSharpCode.Decompiler/Util/Win32Resources.cs

@ -1,4 +1,5 @@
using System; #nullable enable
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Reflection.PortableExecutable; using System.Reflection.PortableExecutable;
@ -15,21 +16,21 @@ namespace ICSharpCode.Decompiler.Util
/// </summary> /// </summary>
/// <param name="pe"></param> /// <param name="pe"></param>
/// <returns></returns> /// <returns></returns>
public static unsafe Win32ResourceDirectory ReadWin32Resources(this PEReader pe) public static unsafe Win32ResourceDirectory? ReadWin32Resources(this PEReader pe)
{ {
if (pe == null) if (pe == null)
{ {
throw new ArgumentNullException(nameof(pe)); throw new ArgumentNullException(nameof(pe));
} }
int rva = pe.PEHeaders.PEHeader.ResourceTableDirectory.RelativeVirtualAddress; int rva = pe.PEHeaders.PEHeader?.ResourceTableDirectory.RelativeVirtualAddress ?? 0;
if (rva == 0) if (rva == 0)
return null; return null;
byte* pRoot = pe.GetSectionData(rva).Pointer; byte* pRoot = pe.GetSectionData(rva).Pointer;
return new Win32ResourceDirectory(pe, pRoot, 0, new Win32ResourceName("Root")); 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) if (root is null)
throw new ArgumentNullException(nameof(root)); throw new ArgumentNullException(nameof(root));
@ -41,7 +42,7 @@ namespace ICSharpCode.Decompiler.Util
return root.FindDirectory(type); 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) if (root is null)
throw new ArgumentNullException(nameof(root)); throw new ArgumentNullException(nameof(root));
@ -55,7 +56,7 @@ namespace ICSharpCode.Decompiler.Util
return root.FindDirectory(type)?.FindDirectory(name); 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) if (root is null)
throw new ArgumentNullException(nameof(root)); throw new ArgumentNullException(nameof(root));
@ -122,7 +123,7 @@ namespace ICSharpCode.Decompiler.Util
return new string(pString->NameString, 0, pString->Length); return new string(pString->NameString, 0, pString->Length);
} }
public Win32ResourceDirectory FindDirectory(Win32ResourceName name) public Win32ResourceDirectory? FindDirectory(Win32ResourceName name)
{ {
foreach (var directory in Directories) foreach (var directory in Directories)
{ {
@ -132,7 +133,7 @@ namespace ICSharpCode.Decompiler.Util
return null; return null;
} }
public Win32ResourceData FindData(Win32ResourceName name) public Win32ResourceData? FindData(Win32ResourceName name)
{ {
foreach (var data in Datas) foreach (var data in Datas)
{ {
@ -142,12 +143,12 @@ namespace ICSharpCode.Decompiler.Util
return null; return null;
} }
public Win32ResourceDirectory FirstDirectory() public Win32ResourceDirectory? FirstDirectory()
{ {
return Directories.Count != 0 ? Directories[0] : null; return Directories.Count != 0 ? Directories[0] : null;
} }
public Win32ResourceData FirstData() public Win32ResourceData? FirstData()
{ {
return Datas.Count != 0 ? Datas[0] : null; return Datas.Count != 0 ? Datas[0] : null;
} }
@ -248,7 +249,7 @@ namespace ICSharpCode.Decompiler.Util
return _name.GetHashCode(); return _name.GetHashCode();
} }
public override bool Equals(object obj) public override bool Equals(object? obj)
{ {
if (!(obj is Win32ResourceName name)) if (!(obj is Win32ResourceName name))
return false; return false;

4
ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net472</TargetFramework> <TargetFramework>net472</TargetFramework>
@ -112,4 +112,4 @@
<Page Include="Cases\Issue445.xaml" /> <Page Include="Cases\Issue445.xaml" />
</ItemGroup> </ItemGroup>
</Project> </Project>

Loading…
Cancel
Save