diff --git a/ICSharpCode.Decompiler.PowerShell/ICSharpCode.Decompiler.PowerShell.csproj b/ICSharpCode.Decompiler.PowerShell/ICSharpCode.Decompiler.PowerShell.csproj index d185475b1..8e73fc14a 100644 --- a/ICSharpCode.Decompiler.PowerShell/ICSharpCode.Decompiler.PowerShell.csproj +++ b/ICSharpCode.Decompiler.PowerShell/ICSharpCode.Decompiler.PowerShell.csproj @@ -5,6 +5,7 @@ true true ICSharpCode.Decompiler.PowerShell + 8.0 diff --git a/ICSharpCode.Decompiler.PowerShell/NullAttributes.cs b/ICSharpCode.Decompiler.PowerShell/NullAttributes.cs new file mode 100644 index 000000000..18662c4e7 --- /dev/null +++ b/ICSharpCode.Decompiler.PowerShell/NullAttributes.cs @@ -0,0 +1,37 @@ +#if !NETCORE + +#nullable enable + +namespace System.Diagnostics.CodeAnalysis +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true)] + internal sealed class NotNullIfNotNullAttribute : Attribute + { + public string ParameterName { get; } + + public NotNullIfNotNullAttribute(string parameterName) + { + ParameterName = parameterName; + } + } + + [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] + internal sealed class NotNullWhenAttribute : Attribute + { + public NotNullWhenAttribute(bool returnValue) + { + ReturnValue = returnValue; + } + + 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 diff --git a/ICSharpCode.ILSpyX/AssemblyList.cs b/ICSharpCode.ILSpyX/AssemblyList.cs index d76402748..90123d643 100644 --- a/ICSharpCode.ILSpyX/AssemblyList.cs +++ b/ICSharpCode.ILSpyX/AssemblyList.cs @@ -23,6 +23,7 @@ using System.Collections.Immutable; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Threading; @@ -70,6 +71,9 @@ namespace ICSharpCode.ILSpyX /// internal AssemblyList() { + ownerThread = Thread.CurrentThread; + manager = null!; + listName = "Testing Only"; } internal AssemblyList(AssemblyListManager manager, string listName) diff --git a/ICSharpCode.ILSpyX/AssemblyListManager.cs b/ICSharpCode.ILSpyX/AssemblyListManager.cs index 02162a9cd..8d2877352 100644 --- a/ICSharpCode.ILSpyX/AssemblyListManager.cs +++ b/ICSharpCode.ILSpyX/AssemblyListManager.cs @@ -53,7 +53,11 @@ namespace ICSharpCode.ILSpyX XElement doc = this.settingsProvider["AssemblyLists"]; foreach (var list in doc.Elements("List")) { - AssemblyLists.Add((string)list.Attribute("name")); + var name = (string?)list.Attribute("name"); + if (name != null) + { + AssemblyLists.Add(name); + } } } @@ -82,7 +86,7 @@ namespace ICSharpCode.ILSpyX { foreach (var list in doc.Elements("List")) { - if ((string)list.Attribute("name") == listName) + if ((string?)list.Attribute("name") == listName) { return new AssemblyList(this, list); } @@ -114,13 +118,13 @@ namespace ICSharpCode.ILSpyX { this.settingsProvider.Update( delegate (XElement root) { - XElement doc = root.Element("AssemblyLists"); + XElement? doc = root.Element("AssemblyLists"); if (doc == null) { doc = new XElement("AssemblyLists"); root.Add(doc); } - XElement listElement = doc.Elements("List").FirstOrDefault(e => (string)e.Attribute("name") == list.ListName); + XElement? listElement = doc.Elements("List").FirstOrDefault(e => (string?)e.Attribute("name") == list.ListName); if (listElement != null) listElement.ReplaceWith(list.SaveAsXml()); else @@ -145,12 +149,12 @@ namespace ICSharpCode.ILSpyX { this.settingsProvider.Update( delegate (XElement root) { - XElement doc = root.Element("AssemblyLists"); + XElement? doc = root.Element("AssemblyLists"); if (doc == null) { return; } - XElement listElement = doc.Elements("List").FirstOrDefault(e => (string)e.Attribute("name") == Name); + XElement? listElement = doc.Elements("List").FirstOrDefault(e => (string?)e.Attribute("name") == Name); if (listElement != null) listElement.Remove(); }); @@ -164,7 +168,7 @@ namespace ICSharpCode.ILSpyX AssemblyLists.Clear(); this.settingsProvider.Update( delegate (XElement root) { - XElement doc = root.Element("AssemblyLists"); + XElement? doc = root.Element("AssemblyLists"); if (doc == null) { return; diff --git a/ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs b/ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs index 724310e07..a8c46f3ea 100644 --- a/ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs +++ b/ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs @@ -50,7 +50,7 @@ namespace ICSharpCode.ILSpyX { if (file == null) throw new ArgumentNullException(nameof(file)); - LoadedAssembly loadedAssembly; + LoadedAssembly? loadedAssembly; lock (LoadedAssembly.loadedAssemblies) { if (!LoadedAssembly.loadedAssemblies.TryGetValue(file, out loadedAssembly)) diff --git a/ICSharpCode.ILSpyX/PdbProvider/DebugInfoUtils.cs b/ICSharpCode.ILSpyX/PdbProvider/DebugInfoUtils.cs index 16cbe284d..cf1cca913 100644 --- a/ICSharpCode.ILSpyX/PdbProvider/DebugInfoUtils.cs +++ b/ICSharpCode.ILSpyX/PdbProvider/DebugInfoUtils.cs @@ -17,8 +17,8 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Diagnostics.CodeAnalysis; using System.IO; -using System.Linq; using System.Reflection.Metadata; using System.Reflection.PortableExecutable; using System.Runtime.InteropServices; @@ -26,24 +26,26 @@ using System.Runtime.InteropServices; using ICSharpCode.Decompiler.DebugInfo; using ICSharpCode.Decompiler.Metadata; +#nullable enable + namespace ICSharpCode.ILSpyX.PdbProvider { public static class DebugInfoUtils { - public static IDebugInfoProvider LoadSymbols(PEFile module) + public static IDebugInfoProvider? LoadSymbols(PEFile module) { try { // try to open portable pdb file/embedded pdb info: if (TryOpenPortablePdb(module, out var provider, out var pdbFileName)) { - return new PortableDebugInfoProvider(pdbFileName, provider, module.FileName); + return new PortableDebugInfoProvider(module.FileName, provider, pdbFileName); } else { // search for pdb in same directory as dll pdbFileName = Path.Combine( - Path.GetDirectoryName(module.FileName), + Path.GetDirectoryName(module.FileName)!, Path.GetFileNameWithoutExtension(module.FileName) + ".pdb" ); if (File.Exists(pdbFileName)) @@ -59,12 +61,12 @@ namespace ICSharpCode.ILSpyX.PdbProvider return null; } - public static IDebugInfoProvider FromFile(PEFile module, string pdbFileName) + public static IDebugInfoProvider? FromFile(PEFile module, string pdbFileName) { if (string.IsNullOrEmpty(pdbFileName)) return null; - Stream stream = OpenStream(pdbFileName); + Stream? stream = OpenStream(pdbFileName); if (stream == null) return null; @@ -78,7 +80,7 @@ namespace ICSharpCode.ILSpyX.PdbProvider { stream.Position = 0; var provider = MetadataReaderProvider.FromPortablePdbStream(stream); - return new PortableDebugInfoProvider(pdbFileName, provider, module.FileName); + return new PortableDebugInfoProvider(module.FileName, provider, pdbFileName); } } @@ -86,7 +88,8 @@ namespace ICSharpCode.ILSpyX.PdbProvider static readonly byte[] buffer = new byte[LegacyPDBPrefix.Length]; static bool TryOpenPortablePdb(PEFile module, - out MetadataReaderProvider provider, out string pdbFileName) + [NotNullWhen(true)] out MetadataReaderProvider? provider, + [NotNullWhen(true)] out string? pdbFileName) { provider = null; pdbFileName = null; @@ -100,12 +103,12 @@ namespace ICSharpCode.ILSpyX.PdbProvider } if (entry.Type == DebugDirectoryEntryType.CodeView) { - string pdbDirectory = Path.GetDirectoryName(module.FileName); + string pdbDirectory = Path.GetDirectoryName(module.FileName)!; pdbFileName = Path.Combine( pdbDirectory, Path.GetFileNameWithoutExtension(module.FileName) + ".pdb"); - if (File.Exists(pdbFileName)) + Stream? stream = OpenStream(pdbFileName); + if (stream != null) { - Stream stream = OpenStream(pdbFileName); if (stream.Read(buffer, 0, buffer.Length) == LegacyPDBPrefix.Length && System.Text.Encoding.ASCII.GetString(buffer) == LegacyPDBPrefix) { @@ -120,7 +123,7 @@ namespace ICSharpCode.ILSpyX.PdbProvider return false; } - static Stream OpenStream(string fileName) + static Stream? OpenStream(string fileName) { if (!File.Exists(fileName)) return null; diff --git a/ICSharpCode.ILSpyX/PdbProvider/MonoCecilDebugInfoProvider.cs b/ICSharpCode.ILSpyX/PdbProvider/MonoCecilDebugInfoProvider.cs index 8d2f9e272..c7e09d305 100644 --- a/ICSharpCode.ILSpyX/PdbProvider/MonoCecilDebugInfoProvider.cs +++ b/ICSharpCode.ILSpyX/PdbProvider/MonoCecilDebugInfoProvider.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection.Metadata.Ecma335; @@ -31,13 +32,15 @@ using Mono.Cecil.Pdb; using SRM = System.Reflection.Metadata; +#nullable enable + namespace ICSharpCode.ILSpyX.PdbProvider { public class MonoCecilDebugInfoProvider : IDebugInfoProvider { readonly Dictionary SequencePoints, IList Variables)> debugInfo; - public unsafe MonoCecilDebugInfoProvider(PEFile module, string pdbFileName, string description = null) + public unsafe MonoCecilDebugInfoProvider(PEFile module, string pdbFileName, string? description = null) { if (module == null) { @@ -49,8 +52,8 @@ namespace ICSharpCode.ILSpyX.PdbProvider throw new ArgumentException("This provider needs access to the full image!"); } + this.SourceFileName = pdbFileName ?? throw new ArgumentNullException(nameof(pdbFileName)); this.Description = description ?? $"Loaded from PDB file: {pdbFileName}"; - this.SourceFileName = pdbFileName; var image = module.Reader.GetEntireImage(); this.debugInfo = new Dictionary SequencePoints, IList Variables)>(); @@ -120,7 +123,7 @@ namespace ICSharpCode.ILSpyX.PdbProvider return info.Variables; } - public bool TryGetName(SRM.MethodDefinitionHandle handle, int index, out string name) + public bool TryGetName(SRM.MethodDefinitionHandle handle, int index, [NotNullWhen(true)] out string? name) { name = null; if (!debugInfo.TryGetValue(handle, out var info)) diff --git a/ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs b/ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs index b04198c80..0f64997ea 100644 --- a/ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs +++ b/ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs @@ -18,28 +18,32 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection.Metadata; using ICSharpCode.Decompiler.DebugInfo; +using ICSharpCode.Decompiler.Util; + +#nullable enable namespace ICSharpCode.ILSpyX.PdbProvider { class PortableDebugInfoProvider : IDebugInfoProvider { - string pdbFileName; + string? pdbFileName; string moduleFileName; readonly MetadataReaderProvider provider; bool hasError; internal bool IsEmbedded => pdbFileName == null; - public PortableDebugInfoProvider(string pdbFileName, MetadataReaderProvider provider, - string moduleFileName) + public PortableDebugInfoProvider(string moduleFileName, MetadataReaderProvider provider, + string? pdbFileName = null) { - this.pdbFileName = pdbFileName; - this.moduleFileName = moduleFileName; + this.moduleFileName = moduleFileName ?? throw new ArgumentNullException(nameof(moduleFileName)); this.provider = provider ?? throw new ArgumentNullException(nameof(provider)); + this.pdbFileName = pdbFileName; } public string Description { @@ -59,7 +63,7 @@ namespace ICSharpCode.ILSpyX.PdbProvider } } - internal MetadataReader GetMetadataReader() + internal MetadataReader? GetMetadataReader() { try { @@ -83,10 +87,10 @@ namespace ICSharpCode.ILSpyX.PdbProvider public IList GetSequencePoints(MethodDefinitionHandle method) { var metadata = GetMetadataReader(); + if (metadata == null) + return EmptyList.Instance; var debugInfo = metadata.GetMethodDebugInformation(method); var sequencePoints = new List(); - if (metadata == null) - return sequencePoints; foreach (var point in debugInfo.GetSequencePoints()) { @@ -135,7 +139,7 @@ namespace ICSharpCode.ILSpyX.PdbProvider return variables; } - public bool TryGetName(MethodDefinitionHandle method, int index, out string name) + public bool TryGetName(MethodDefinitionHandle method, int index, [NotNullWhen(true)] out string? name) { var metadata = GetMetadataReader(); name = null;