From 5fb2f7a22fb4d830254b7162aba4d6c6f66421e3 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Thu, 3 Jun 2021 21:36:12 +0200 Subject: [PATCH] #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;