Browse Source

Fix nullability warnings

pull/2650/head
Siegfried Pammer 3 years ago
parent
commit
31f6be38b5
  1. 12
      ILSpy/AssemblyList.cs
  2. 2
      ILSpy/AssemblyListSnapshot.cs
  3. 18
      ILSpy/ExtensionMethods.cs
  4. 60
      ILSpy/LoadedAssembly.cs
  5. 70
      ILSpy/TextView/DecompilerTextView.cs

12
ILSpy/AssemblyList.cs

@ -72,7 +72,7 @@ namespace ICSharpCode.ILSpy
/// Loads an assembly list from XML. /// Loads an assembly list from XML.
/// </summary> /// </summary>
public AssemblyList(XElement listElement) public AssemblyList(XElement listElement)
: this((string)listElement.Attribute("name")) : this((string?)listElement.Attribute("name") ?? AssemblyListManager.DefaultListName)
{ {
foreach (var asm in listElement.Elements("Assembly")) foreach (var asm in listElement.Elements("Assembly"))
{ {
@ -184,7 +184,7 @@ namespace ICSharpCode.ILSpy
} }
} }
void Assemblies_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) void Assemblies_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{ {
Debug.Assert(Monitor.IsEntered(lockObj)); Debug.Assert(Monitor.IsEntered(lockObj));
if (CollectionChangeHasEffectOnSave(e)) if (CollectionChangeHasEffectOnSave(e))
@ -199,9 +199,9 @@ namespace ICSharpCode.ILSpy
switch (e.Action) switch (e.Action)
{ {
case NotifyCollectionChangedAction.Add: case NotifyCollectionChangedAction.Add:
return e.NewItems.Cast<LoadedAssembly>().Any(asm => !asm.IsAutoLoaded); return e.NewItems.EmptyIfNull().Cast<LoadedAssembly>().Any(asm => !asm.IsAutoLoaded);
case NotifyCollectionChangedAction.Remove: case NotifyCollectionChangedAction.Remove:
return e.OldItems.Cast<LoadedAssembly>().Any(asm => !asm.IsAutoLoaded); return e.OldItems.EmptyIfNull().Cast<LoadedAssembly>().Any(asm => !asm.IsAutoLoaded);
default: default:
return true; return true;
} }
@ -283,7 +283,7 @@ namespace ICSharpCode.ILSpy
{ {
bool isUIThread = App.Current.Dispatcher.Thread == Thread.CurrentThread; bool isUIThread = App.Current.Dispatcher.Thread == Thread.CurrentThread;
LoadedAssembly asm; LoadedAssembly? asm;
lock (lockObj) lock (lockObj)
{ {
if (byFilename.TryGetValue(file, out asm)) if (byFilename.TryGetValue(file, out asm))
@ -319,7 +319,7 @@ namespace ICSharpCode.ILSpy
file = Path.GetFullPath(file); file = Path.GetFullPath(file);
lock (lockObj) lock (lockObj)
{ {
if (!byFilename.TryGetValue(file, out LoadedAssembly target)) if (!byFilename.TryGetValue(file, out LoadedAssembly? target))
return null; return null;
int index = this.assemblies.IndexOf(target); int index = this.assemblies.IndexOf(target);
if (index < 0) if (index < 0)

2
ILSpy/AssemblyListSnapshot.cs

@ -56,7 +56,7 @@ namespace ICSharpCode.ILSpy
lookup = await CreateLoadedAssemblyLookupAsync(shortNames: isWinRT).ConfigureAwait(false); lookup = await CreateLoadedAssemblyLookupAsync(shortNames: isWinRT).ConfigureAwait(false);
lookup = LazyInit.GetOrSet(ref isWinRT ? ref asmLookupByShortName : ref asmLookupByFullName, lookup); lookup = LazyInit.GetOrSet(ref isWinRT ? ref asmLookupByShortName : ref asmLookupByFullName, lookup);
} }
if (lookup.TryGetValue(key, out PEFile module)) if (lookup.TryGetValue(key, out PEFile? module))
return module; return module;
return null; return null;
} }

18
ILSpy/ExtensionMethods.cs

@ -16,12 +16,17 @@
// 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.Generic; using System.Collections.Generic;
using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy.Options; using ICSharpCode.ILSpy.Options;
namespace ICSharpCode.ILSpy namespace ICSharpCode.ILSpy
@ -38,7 +43,7 @@ namespace ICSharpCode.ILSpy
list.Add(item); list.Add(item);
} }
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);
@ -118,6 +123,11 @@ namespace ICSharpCode.ILSpy
value = pair.Value; value = pair.Value;
} }
internal static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T>? inst) => inst ?? Enumerable.Empty<T>();
internal static IEnumerable EmptyIfNull(this IEnumerable? inst) => inst ?? Enumerable.Empty<object>();
internal static IList<T> EmptyIfNull<T>(this IList<T>? inst) => inst ?? EmptyList<T>.Instance;
internal static IList EmptyIfNull(this IList? inst) => inst ?? Array.Empty<object>();
public static string ToSuffixString(this System.Reflection.Metadata.EntityHandle handle) public static string ToSuffixString(this System.Reflection.Metadata.EntityHandle handle)
{ {
if (!DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokens) if (!DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokens)
@ -218,7 +228,7 @@ namespace ICSharpCode.ILSpy
} }
#endregion #endregion
public static T FindVisualChild<T>(this DependencyObject depObj) where T : DependencyObject public static T? FindVisualChild<T>(this DependencyObject? depObj) where T : DependencyObject
{ {
if (depObj != null) if (depObj != null)
{ {
@ -230,7 +240,7 @@ namespace ICSharpCode.ILSpy
return (T)child; return (T)child;
} }
T childItem = FindVisualChild<T>(child); T? childItem = FindVisualChild<T>(child);
if (childItem != null) if (childItem != null)
return childItem; return childItem;
} }
@ -238,7 +248,7 @@ namespace ICSharpCode.ILSpy
return null; return null;
} }
public static T GetParent<T>(this DependencyObject depObj) where T : DependencyObject public static T? GetParent<T>(this DependencyObject? depObj) where T : DependencyObject
{ {
if (depObj == null) if (depObj == null)
return null; return null;

60
ILSpy/LoadedAssembly.cs

@ -218,7 +218,7 @@ namespace ICSharpCode.ILSpy
return LazyInitializer.EnsureInitialized(ref this.typeSystem, () => { return LazyInitializer.EnsureInitialized(ref this.typeSystem, () => {
var module = GetPEFileOrNull(); var module = GetPEFileOrNull();
if (module == null) if (module == null)
return null; return null!;
return new SimpleCompilation( return new SimpleCompilation(
module.WithOptions(TypeSystemOptions.Default | TypeSystemOptions.Uncached | TypeSystemOptions.KeepModifiers), module.WithOptions(TypeSystemOptions.Default | TypeSystemOptions.Uncached | TypeSystemOptions.KeepModifiers),
MinimalCorlib.Instance); MinimalCorlib.Instance);
@ -580,42 +580,44 @@ namespace ICSharpCode.ILSpy
return module; return module;
} }
string? directory = Path.GetDirectoryName(mainModule.FileName);
string file = Path.Combine(Path.GetDirectoryName(mainModule.FileName), moduleName); if (directory != null)
if (File.Exists(file))
{ {
// Load module from disk string file = Path.Combine(directory, moduleName);
LoadedAssembly? asm; if (File.Exists(file))
if (loadOnDemand)
{ {
asm = assemblyList.OpenAssembly(file, isAutoLoaded: true); // Load module from disk
} LoadedAssembly? asm;
else if (loadOnDemand)
{ {
asm = assemblyList.FindAssembly(file); asm = assemblyList.OpenAssembly(file, isAutoLoaded: true);
} }
if (asm != null) else
{ {
return await asm.GetPEFileOrNullAsync().ConfigureAwait(false); asm = assemblyList.FindAssembly(file);
}
if (asm != null)
{
return await asm.GetPEFileOrNullAsync().ConfigureAwait(false);
}
} }
} }
else
// Module does not exist on disk, look for one with a matching name in the assemblylist:
foreach (LoadedAssembly loaded in alreadyLoadedAssemblies.Assemblies)
{ {
// Module does not exist on disk, look for one with a matching name in the assemblylist: var module = await loaded.GetPEFileOrNullAsync().ConfigureAwait(false);
foreach (LoadedAssembly loaded in alreadyLoadedAssemblies.Assemblies) var reader = module?.Metadata;
if (reader == null || reader.IsAssembly)
continue;
var moduleDef = reader.GetModuleDefinition();
if (moduleName.Equals(reader.GetString(moduleDef.Name), StringComparison.OrdinalIgnoreCase))
{ {
var module = await loaded.GetPEFileOrNullAsync().ConfigureAwait(false); referenceLoadInfo.AddMessageOnce(moduleName, MessageKind.Info, "Success - Found in Assembly List");
var reader = module?.Metadata; return module;
if (reader == null || reader.IsAssembly)
continue;
var moduleDef = reader.GetModuleDefinition();
if (moduleName.Equals(reader.GetString(moduleDef.Name), StringComparison.OrdinalIgnoreCase))
{
referenceLoadInfo.AddMessageOnce(moduleName, MessageKind.Info, "Success - Found in Assembly List");
return module;
}
} }
} }
return null; return null;
} }
} }

70
ILSpy/TextView/DecompilerTextView.cs

@ -170,7 +170,7 @@ namespace ICSharpCode.ILSpy.TextView
#region Line margin #region Line margin
void CurrentDisplaySettings_PropertyChanged(object sender, PropertyChangedEventArgs e) void CurrentDisplaySettings_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{ {
if (e.PropertyName == nameof(DisplaySettings.ShowLineNumbers)) if (e.PropertyName == nameof(DisplaySettings.ShowLineNumbers))
{ {
@ -216,7 +216,7 @@ namespace ICSharpCode.ILSpy.TextView
int offset = textEditor.Document.GetOffset(position.Value.Location); int offset = textEditor.Document.GetOffset(position.Value.Location);
if (referenceElementGenerator.References == null) if (referenceElementGenerator.References == null)
return; return;
ReferenceSegment seg = referenceElementGenerator.References.FindSegmentsContaining(offset).FirstOrDefault(); ReferenceSegment? seg = referenceElementGenerator.References.FindSegmentsContaining(offset).FirstOrDefault();
if (seg == null) if (seg == null)
return; return;
object? content = GenerateTooltip(seg); object? content = GenerateTooltip(seg);
@ -363,7 +363,7 @@ namespace ICSharpCode.ILSpy.TextView
TryCloseExistingPopup(true); TryCloseExistingPopup(true);
} }
void ToolTipClosed(object sender, EventArgs e) void ToolTipClosed(object? sender, EventArgs e)
{ {
if (toolTip == sender) if (toolTip == sender)
{ {
@ -373,7 +373,10 @@ namespace ICSharpCode.ILSpy.TextView
{ {
// Because popupToolTip instances are created by the tooltip provider, // Because popupToolTip instances are created by the tooltip provider,
// they might be reused; so we should detach the event handler // they might be reused; so we should detach the event handler
popupToolTip.Closed -= ToolTipClosed; if (popupToolTip != null)
{
popupToolTip.Closed -= ToolTipClosed;
}
popupToolTip = null; popupToolTip = null;
} }
} }
@ -515,7 +518,7 @@ namespace ICSharpCode.ILSpy.TextView
#endregion #endregion
#region Highlight brackets #region Highlight brackets
void HighlightBrackets(object sender, EventArgs e) void HighlightBrackets(object? sender, EventArgs e)
{ {
if (DisplaySettingsPanel.CurrentDisplaySettings.HighlightMatchingBraces) if (DisplaySettingsPanel.CurrentDisplaySettings.HighlightMatchingBraces)
{ {
@ -569,7 +572,9 @@ namespace ICSharpCode.ILSpy.TextView
currentCancellationTokenSource = myCancellationTokenSource; currentCancellationTokenSource = myCancellationTokenSource;
// cancel the previous only after current was set to the new one (avoid that the old one still finishes successfully) // cancel the previous only after current was set to the new one (avoid that the old one still finishes successfully)
if (previousCancellationTokenSource != null) if (previousCancellationTokenSource != null)
{
previousCancellationTokenSource.Cancel(); previousCancellationTokenSource.Cancel();
}
var tcs = new TaskCompletionSource<T>(); var tcs = new TaskCompletionSource<T>();
Task<T> task; Task<T> task;
@ -1248,29 +1253,52 @@ namespace ICSharpCode.ILSpy.TextView
{ {
return other != null return other != null
&& ViewedUri == other.ViewedUri && ViewedUri == other.ViewedUri
&& (DecompiledNodes == other.DecompiledNodes || DecompiledNodes?.SetEquals(other.DecompiledNodes) == true); && NullSafeSetEquals(DecompiledNodes, other.DecompiledNodes);
static bool NullSafeSetEquals(HashSet<ILSpyTreeNode>? a, HashSet<ILSpyTreeNode>? b)
{
if (a == b)
return true;
if (a == null || b == null)
return false;
return a.SetEquals(b);
}
} }
} }
public class DecompilerTextViewState : ViewState public class DecompilerTextViewState : ViewState
{ {
private List<Tuple<int, int>>? ExpandedFoldings; private List<(int StartOffset, int EndOffset)>? ExpandedFoldings;
private int FoldingsChecksum; private int FoldingsChecksum;
public double VerticalOffset; public double VerticalOffset;
public double HorizontalOffset; public double HorizontalOffset;
public void SaveFoldingsState(IEnumerable<FoldingSection> foldings) public void SaveFoldingsState(IEnumerable<FoldingSection> foldings)
{ {
ExpandedFoldings = foldings.Where(f => !f.IsFolded).Select(f => Tuple.Create(f.StartOffset, f.EndOffset)).ToList(); ExpandedFoldings = foldings.Where(f => !f.IsFolded)
FoldingsChecksum = unchecked(foldings.Select(f => f.StartOffset * 3 - f.EndOffset).DefaultIfEmpty().Aggregate((a, b) => a + b)); .Select(f => (f.StartOffset, f.EndOffset)).ToList();
FoldingsChecksum = unchecked(foldings.Select(f => f.StartOffset * 3 - f.EndOffset)
.DefaultIfEmpty()
.Aggregate((a, b) => a + b));
} }
internal void RestoreFoldings(List<NewFolding> list) internal void RestoreFoldings(List<NewFolding> list)
{ {
var checksum = unchecked(list.Select(f => f.StartOffset * 3 - f.EndOffset).DefaultIfEmpty().Aggregate((a, b) => a + b)); if (ExpandedFoldings == null)
return;
var checksum = unchecked(list.Select(f => f.StartOffset * 3 - f.EndOffset)
.DefaultIfEmpty()
.Aggregate((a, b) => a + b));
if (FoldingsChecksum == checksum) if (FoldingsChecksum == checksum)
{
foreach (var folding in list) foreach (var folding in list)
folding.DefaultClosed = !ExpandedFoldings.Any(f => f.Item1 == folding.StartOffset && f.Item2 == folding.EndOffset); {
folding.DefaultClosed = !ExpandedFoldings.Any(
f => f.StartOffset == folding.StartOffset
&& f.EndOffset == folding.EndOffset
);
}
}
} }
public override bool Equals(ViewState? other) public override bool Equals(ViewState? other)
@ -1301,17 +1329,21 @@ namespace ICSharpCode.ILSpy.TextView
resourceName += ".xshd"; resourceName += ".xshd";
manager.RegisterHighlighting( Stream? resourceStream = typeof(DecompilerTextView).Assembly
name, extensions, .GetManifestResourceStream(typeof(DecompilerTextView), resourceName);
delegate {
using (Stream s = typeof(DecompilerTextView).Assembly.GetManifestResourceStream(typeof(DecompilerTextView), resourceName)) if (resourceStream != null)
{ {
using (XmlTextReader reader = new XmlTextReader(s)) manager.RegisterHighlighting(
name, extensions,
delegate {
using (resourceStream)
using (XmlTextReader reader = new XmlTextReader(resourceStream))
{ {
return HighlightingLoader.Load(reader, manager); return HighlightingLoader.Load(reader, manager);
} }
} });
}); }
} }
} }
} }

Loading…
Cancel
Save