diff --git a/ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs b/ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs index 138ecd3c1..8a8619080 100644 --- a/ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs +++ b/ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs @@ -21,21 +21,21 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; -#nullable disable - using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions; namespace ICSharpCode.ILSpyX.TreeView { public partial class SharpTreeNode : INotifyPropertyChanged { + [AllowNull] protected static ITreeNodeImagesProvider ImagesProvider { get; private set; } public static void SetImagesProvider(ITreeNodeImagesProvider provider) => ImagesProvider = provider; - SharpTreeNodeCollection modelChildren; - internal SharpTreeNode modelParent; + SharpTreeNodeCollection? modelChildren; + internal SharpTreeNode? modelParent; bool isVisible = true; void UpdateIsVisible(bool parentIsVisible, bool updateFlattener) @@ -53,7 +53,7 @@ namespace ICSharpCode.ILSpyX.TreeView node = node.listParent; } // Remember the removed nodes: - List removedNodes = null; + List? removedNodes = null; if (updateFlattener && !newIsVisible) { removedNodes = VisibleDescendantsAndSelf().ToList(); @@ -118,19 +118,19 @@ namespace ICSharpCode.ILSpyX.TreeView } } - public SharpTreeNode Parent { + public SharpTreeNode? Parent { get { return modelParent; } } - public virtual object Text { + public virtual object? Text { get { return null; } } - public virtual object Icon { + public virtual object? Icon { get { return null; } } - public virtual object ToolTip { + public virtual object? ToolTip { get { return null; } } @@ -199,7 +199,7 @@ namespace ICSharpCode.ILSpyX.TreeView while (removeEnd.modelChildren != null && removeEnd.modelChildren.Count > 0) removeEnd = removeEnd.modelChildren.Last(); - List removedNodes = null; + List? removedNodes = null; int visibleIndexOfRemoval = 0; if (node.isVisible) { @@ -221,11 +221,11 @@ namespace ICSharpCode.ILSpyX.TreeView } if (e.NewItems != null) { - SharpTreeNode insertionPos; + SharpTreeNode? insertionPos; if (e.NewStartingIndex == 0) insertionPos = null; else - insertionPos = modelChildren[e.NewStartingIndex - 1]; + insertionPos = modelChildren?[e.NewStartingIndex - 1]; foreach (SharpTreeNode node in e.NewItems) { @@ -260,7 +260,7 @@ namespace ICSharpCode.ILSpyX.TreeView #region Expanding / LazyLoading - public virtual object ExpandedIcon { + public virtual object? ExpandedIcon { get { return Icon; } } @@ -371,13 +371,13 @@ namespace ICSharpCode.ILSpyX.TreeView public IEnumerable Ancestors() { - for (SharpTreeNode n = this.Parent; n != null; n = n.Parent) + for (SharpTreeNode? n = this.Parent; n != null; n = n.Parent) yield return n; } public IEnumerable AncestorsAndSelf() { - for (SharpTreeNode n = this; n != null; n = n.Parent) + for (SharpTreeNode? n = this; n != null; n = n.Parent) yield return n; } @@ -402,7 +402,7 @@ namespace ICSharpCode.ILSpyX.TreeView } } - public virtual string LoadEditText() + public virtual string? LoadEditText() { return null; } @@ -699,7 +699,7 @@ namespace ICSharpCode.ILSpyX.TreeView #region INotifyPropertyChanged Members - public event PropertyChangedEventHandler PropertyChanged; + public event PropertyChangedEventHandler? PropertyChanged; public void RaisePropertyChanged(string name) { @@ -725,10 +725,10 @@ namespace ICSharpCode.ILSpyX.TreeView { } - public override string ToString() + public override string? ToString() { // used for keyboard navigation - object text = this.Text; + object? text = this.Text; return text != null ? text.ToString() : string.Empty; } } diff --git a/ILSpy/Analyzers/AnalyzerEntityTreeNode.cs b/ILSpy/Analyzers/AnalyzerEntityTreeNode.cs index 039230e85..c86dc1e80 100644 --- a/ILSpy/Analyzers/AnalyzerEntityTreeNode.cs +++ b/ILSpy/Analyzers/AnalyzerEntityTreeNode.cs @@ -35,7 +35,7 @@ namespace ICSharpCode.ILSpy.Analyzers /// public abstract class AnalyzerEntityTreeNode : AnalyzerTreeNode, IMemberTreeNode { - public abstract IEntity Member { get; } + public abstract IEntity? Member { get; } public IEntity? SourceMember { get; protected set; } @@ -65,13 +65,12 @@ namespace ICSharpCode.ILSpy.Analyzers } foreach (LoadedAssembly asm in removedAssemblies) { - if (this.Member.ParentModule.MetadataFile == asm.GetMetadataFileOrNull()) + if (this.Member.ParentModule!.MetadataFile == asm.GetMetadataFileOrNull()) return false; // remove this node } this.Children.RemoveAll( delegate (SharpTreeNode n) { - AnalyzerTreeNode an = n as AnalyzerTreeNode; - return an == null || !an.HandleAssemblyListChanged(removedAssemblies, addedAssemblies); + return n is not AnalyzerTreeNode an || !an.HandleAssemblyListChanged(removedAssemblies, addedAssemblies); }); return true; } diff --git a/ILSpy/Analyzers/TreeNodes/AnalyzedEventTreeNode.cs b/ILSpy/Analyzers/TreeNodes/AnalyzedEventTreeNode.cs index 3ef317edc..a197ed0a2 100644 --- a/ILSpy/Analyzers/TreeNodes/AnalyzedEventTreeNode.cs +++ b/ILSpy/Analyzers/TreeNodes/AnalyzedEventTreeNode.cs @@ -17,6 +17,8 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.ILSpy.TreeNodes; @@ -57,6 +59,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes foreach (var lazy in Analyzers) { var analyzer = lazy.Value; + Debug.Assert(analyzer != null); if (analyzer.Show(analyzedEvent)) { this.Children.Add(new AnalyzerSearchTreeNode(analyzedEvent, analyzer, lazy.Metadata?.Header)); @@ -64,10 +67,10 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes } } - bool TryFindBackingField(IEvent analyzedEvent, out IField backingField) + bool TryFindBackingField(IEvent analyzedEvent, [NotNullWhen(true)] out IField? backingField) { backingField = null; - foreach (var field in analyzedEvent.DeclaringTypeDefinition.GetFields(options: GetMemberOptions.IgnoreInheritedMembers)) + foreach (var field in analyzedEvent.DeclaringTypeDefinition?.GetFields(options: GetMemberOptions.IgnoreInheritedMembers) ?? []) { if (field.Name == analyzedEvent.Name && field.Accessibility == Decompiler.TypeSystem.Accessibility.Private) { diff --git a/ILSpy/Analyzers/TreeNodes/AnalyzedFieldTreeNode.cs b/ILSpy/Analyzers/TreeNodes/AnalyzedFieldTreeNode.cs index acfe6880b..48831a67c 100644 --- a/ILSpy/Analyzers/TreeNodes/AnalyzedFieldTreeNode.cs +++ b/ILSpy/Analyzers/TreeNodes/AnalyzedFieldTreeNode.cs @@ -17,6 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Diagnostics; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.ILSpy.TreeNodes; @@ -45,6 +46,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes foreach (var lazy in Analyzers) { var analyzer = lazy.Value; + Debug.Assert(analyzer != null); if (analyzer.Show(analyzedField)) { this.Children.Add(new AnalyzerSearchTreeNode(analyzedField, analyzer, lazy.Metadata?.Header)); diff --git a/ILSpy/Analyzers/TreeNodes/AnalyzedMethodTreeNode.cs b/ILSpy/Analyzers/TreeNodes/AnalyzedMethodTreeNode.cs index 711ffd05c..421c9bf2d 100644 --- a/ILSpy/Analyzers/TreeNodes/AnalyzedMethodTreeNode.cs +++ b/ILSpy/Analyzers/TreeNodes/AnalyzedMethodTreeNode.cs @@ -17,6 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Diagnostics; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.ILSpy.TreeNodes; @@ -47,9 +48,10 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes foreach (var lazy in Analyzers) { var analyzer = lazy.Value; + Debug.Assert(analyzer != null); if (analyzer.Show(analyzedMethod)) { - this.Children.Add(new AnalyzerSearchTreeNode(analyzedMethod, analyzer, lazy.Metadata.Header)); + this.Children.Add(new AnalyzerSearchTreeNode(analyzedMethod, analyzer, lazy.Metadata!.Header)); } } } diff --git a/ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs b/ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs index cde606d36..7695b625f 100644 --- a/ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs +++ b/ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Windows; using ICSharpCode.Decompiler.TypeSystem; @@ -44,16 +45,17 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes public override object Text => analyzedModule.AssemblyName; - public override object ToolTip => analyzedModule.MetadataFile?.FileName; + public override object? ToolTip => analyzedModule.MetadataFile?.FileName; protected override void LoadChildren() { foreach (var lazy in Analyzers) { var analyzer = lazy.Value; + Debug.Assert(analyzer != null); if (analyzer.Show(analyzedModule)) { - this.Children.Add(new AnalyzerSearchTreeNode(analyzedModule, analyzer, lazy.Metadata.Header)); + this.Children.Add(new AnalyzerSearchTreeNode(analyzedModule, analyzer, lazy.Metadata!.Header)); } } } @@ -69,7 +71,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes MessageBus.Send(this, new NavigateToReferenceEventArgs(analyzedModule.MetadataFile)); } - public override IEntity Member => null; + public override IEntity? Member => null; public override bool HandleAssemblyListChanged(ICollection removedAssemblies, ICollection addedAssemblies) { @@ -84,8 +86,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes } this.Children.RemoveAll( delegate (SharpTreeNode n) { - AnalyzerTreeNode an = n as AnalyzerTreeNode; - return an == null || !an.HandleAssemblyListChanged(removedAssemblies, addedAssemblies); + return n is not AnalyzerTreeNode an || !an.HandleAssemblyListChanged(removedAssemblies, addedAssemblies); }); return true; } diff --git a/ILSpy/Analyzers/TreeNodes/AnalyzedPropertyTreeNode.cs b/ILSpy/Analyzers/TreeNodes/AnalyzedPropertyTreeNode.cs index c306caf82..4de437182 100644 --- a/ILSpy/Analyzers/TreeNodes/AnalyzedPropertyTreeNode.cs +++ b/ILSpy/Analyzers/TreeNodes/AnalyzedPropertyTreeNode.cs @@ -17,6 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Diagnostics; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.ILSpy.TreeNodes; @@ -53,9 +54,10 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes foreach (var lazy in Analyzers) { var analyzer = lazy.Value; + Debug.Assert(analyzer != null); if (analyzer.Show(analyzedProperty)) { - this.Children.Add(new AnalyzerSearchTreeNode(analyzedProperty, analyzer, lazy.Metadata.Header)); + this.Children.Add(new AnalyzerSearchTreeNode(analyzedProperty, analyzer, lazy.Metadata!.Header)); } } } diff --git a/ILSpy/Analyzers/TreeNodes/AnalyzedTypeTreeNode.cs b/ILSpy/Analyzers/TreeNodes/AnalyzedTypeTreeNode.cs index 7ae84a094..c4cd300ce 100644 --- a/ILSpy/Analyzers/TreeNodes/AnalyzedTypeTreeNode.cs +++ b/ILSpy/Analyzers/TreeNodes/AnalyzedTypeTreeNode.cs @@ -17,6 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Diagnostics; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.ILSpy.TreeNodes; @@ -45,9 +46,10 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes foreach (var lazy in Analyzers) { var analyzer = lazy.Value; + Debug.Assert(analyzer != null); if (analyzer.Show(analyzedType)) { - this.Children.Add(new AnalyzerSearchTreeNode(analyzedType, analyzer, lazy.Metadata.Header)); + this.Children.Add(new AnalyzerSearchTreeNode(analyzedType, analyzer, lazy.Metadata!.Header)); } } } diff --git a/ILSpy/AssemblyTree/AssemblyTreeModel.cs b/ILSpy/AssemblyTree/AssemblyTreeModel.cs index 0e9b98f30..c201179c1 100644 --- a/ILSpy/AssemblyTree/AssemblyTreeModel.cs +++ b/ILSpy/AssemblyTree/AssemblyTreeModel.cs @@ -602,7 +602,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree List path = new List(); while (node.Parent != null) { - path.Add(node.ToString()); + path.Add(node.ToString()!); node = node.Parent; } path.Reverse(); diff --git a/ILSpy/TextView/DecompilerTextView.cs b/ILSpy/TextView/DecompilerTextView.cs index 5ad397a07..f8da82342 100644 --- a/ILSpy/TextView/DecompilerTextView.cs +++ b/ILSpy/TextView/DecompilerTextView.cs @@ -1100,7 +1100,11 @@ namespace ICSharpCode.ILSpy.TextView SaveFileDialog dlg = new SaveFileDialog(); dlg.DefaultExt = language.FileExtension; dlg.Filter = language.Name + "|*" + language.FileExtension + Properties.Resources.AllFiles; - dlg.FileName = WholeProjectDecompiler.CleanUpFileName(treeNodes.First().Text.ToString(), language.FileExtension); + string? nodeText = treeNodes.First().Text?.ToString(); + if (!string.IsNullOrWhiteSpace(nodeText)) + { + dlg.FileName = WholeProjectDecompiler.CleanUpFileName(nodeText, language.FileExtension); + } if (dlg.ShowDialog() == true) { SaveToDisk(new DecompilationContext(language, treeNodes.ToArray(), options), dlg.FileName);