Browse Source

#nullable enable for ILAst (except for generated code)

issue1638
Daniel Grunwald 4 years ago
parent
commit
5fb2f7a22f
  1. 4
      ICSharpCode.Decompiler/CSharp/Resolver/CSharpOperators.cs
  2. 7
      ICSharpCode.Decompiler/IL/ILAstWritingOptions.cs
  3. 5
      ICSharpCode.Decompiler/IL/ILInstructionExtensions.cs
  4. 7
      ICSharpCode.Decompiler/IL/ILTypeExtensions.cs
  5. 20
      ICSharpCode.Decompiler/IL/ILVariable.cs
  6. 3
      ICSharpCode.Decompiler/IL/InstructionFlags.cs
  7. 3
      ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs
  8. 7
      ICSharpCode.Decompiler/IL/Instructions/Await.cs
  9. 5
      ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs
  10. 41
      ICSharpCode.Decompiler/IL/Instructions/Block.cs
  11. 32
      ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs
  12. 25
      ICSharpCode.Decompiler/IL/Instructions/Branch.cs
  13. 5
      ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs
  14. 15
      ICSharpCode.Decompiler/IL/Instructions/CallInstruction.cs
  15. 6
      ICSharpCode.Decompiler/IL/Instructions/Comp.cs
  16. 5
      ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs
  17. 3
      ICSharpCode.Decompiler/IL/Instructions/Conv.cs
  18. 9
      ICSharpCode.Decompiler/IL/Instructions/DeconstructResultInstruction.cs
  19. 3
      ICSharpCode.Decompiler/IL/Instructions/DefaultValue.cs
  20. 41
      ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs
  21. 3
      ICSharpCode.Decompiler/IL/Instructions/ExpressionTreeCast.cs
  22. 30
      ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs
  23. 2
      ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs
  24. 5
      ICSharpCode.Decompiler/IL/Instructions/ILVariableCollection.cs
  25. 9
      ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs
  26. 3
      ICSharpCode.Decompiler/IL/Instructions/LdFlda.cs
  27. 3
      ICSharpCode.Decompiler/IL/Instructions/LdLen.cs
  28. 13
      ICSharpCode.Decompiler/IL/Instructions/Leave.cs
  29. 3
      ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs
  30. 3
      ICSharpCode.Decompiler/IL/Instructions/LogicInstructions.cs
  31. 14
      ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs
  32. 3
      ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs
  33. 3
      ICSharpCode.Decompiler/IL/Instructions/NullCoalescingInstruction.cs
  34. 3
      ICSharpCode.Decompiler/IL/Instructions/NullableInstructions.cs
  35. 75
      ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs
  36. 13
      ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs
  37. 7
      ICSharpCode.Decompiler/IL/Instructions/StLoc.cs
  38. 13
      ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs
  39. 4
      ICSharpCode.Decompiler/IL/Instructions/SwitchInstruction.cs
  40. 11
      ICSharpCode.Decompiler/IL/Instructions/TryInstruction.cs
  41. 3
      ICSharpCode.Decompiler/IL/Instructions/UnaryInstruction.cs
  42. 3
      ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs
  43. 16
      ICSharpCode.Decompiler/IL/Patterns/AnyNode.cs
  44. 13
      ICSharpCode.Decompiler/IL/Patterns/ListMatch.cs
  45. 5
      ICSharpCode.Decompiler/IL/Patterns/Match.cs
  46. 3
      ICSharpCode.Decompiler/IL/PrimitiveType.cs
  47. 4
      ICSharpCode.Decompiler/IL/SemanticHelper.cs
  48. 1
      ICSharpCode.Decompiler/IL/SlotInfo.cs
  49. 1
      ICSharpCode.Decompiler/IL/StackType.cs
  50. 6
      ICSharpCode.Decompiler/TypeSystem/IMember.cs
  51. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/SyntheticRangeIndexer.cs

4
ICSharpCode.Decompiler/CSharp/Resolver/CSharpOperators.cs

@ -128,9 +128,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
get { return null; } get { return null; }
} }
IType IEntity.DeclaringType { public IType DeclaringType => SpecialType.UnknownType;
get { return null; }
}
IMember IMember.MemberDefinition { IMember IMember.MemberDefinition {
get { return this; } get { return this; }

7
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -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)); OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
} }
@ -94,6 +95,6 @@ namespace ICSharpCode.Decompiler.IL
PropertyChanged?.Invoke(this, e); PropertyChanged?.Invoke(this, e);
} }
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler? PropertyChanged;
} }
} }

5
ICSharpCode.Decompiler/IL/ILInstructionExtensions.cs

@ -1,4 +1,5 @@
using System; #nullable enable
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
@ -20,7 +21,7 @@ namespace ICSharpCode.Decompiler.IL
return target; return target;
} }
public static ILInstruction GetNextSibling(this ILInstruction instruction) public static ILInstruction? GetNextSibling(this ILInstruction? instruction)
{ {
if (instruction?.Parent == null) if (instruction?.Parent == null)
return null; return null;

7
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -145,12 +146,12 @@ namespace ICSharpCode.Decompiler.IL
/// ///
/// Returns SpecialType.UnknownType for unsupported instructions. /// Returns SpecialType.UnknownType for unsupported instructions.
/// </summary> /// </summary>
public static IType InferType(this ILInstruction inst, ICompilation compilation) public static IType InferType(this ILInstruction inst, ICompilation? compilation)
{ {
switch (inst) switch (inst)
{ {
case NewObj newObj: case NewObj newObj:
return newObj.Method.DeclaringType; return newObj.Method.DeclaringType ?? SpecialType.UnknownType;
case NewArr newArr: case NewArr newArr:
if (compilation != null) if (compilation != null)
return new ArrayType(compilation, newArr.Type, newArr.Indices.Count); return new ArrayType(compilation, newArr.Type, newArr.Indices.Count);

20
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -19,7 +20,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem; 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; } public bool HasGeneratedName { get; set; }
@ -202,7 +202,7 @@ namespace ICSharpCode.Decompiler.IL
/// <remarks> /// <remarks>
/// This property is set automatically when the variable is added to the <c>ILFunction.Variables</c> collection. /// This property is set automatically when the variable is added to the <c>ILFunction.Variables</c> collection.
/// </remarks> /// </remarks>
public ILFunction Function { get; internal set; } public ILFunction? Function { get; internal set; }
/// <summary> /// <summary>
/// Gets the block container in which this variable is captured. /// Gets the block container in which this variable is captured.
@ -212,7 +212,7 @@ namespace ICSharpCode.Decompiler.IL
/// <remarks> /// <remarks>
/// This property returns null for variables that are not captured. /// This property returns null for variables that are not captured.
/// </remarks> /// </remarks>
public BlockContainer CaptureScope { get; internal set; } public BlockContainer? CaptureScope { get; internal set; }
/// <summary> /// <summary>
/// Gets the index of this variable within the <c>Function.Variables</c> collection. /// Gets the index of this variable within the <c>Function.Variables</c> collection.
@ -309,7 +309,7 @@ namespace ICSharpCode.Decompiler.IL
return list.Count - 1; return list.Count - 1;
} }
void RemoveInstruction<T>(List<T> list, int index, T inst) where T : class, IInstructionWithVariableOperand void RemoveInstruction<T>(List<T> list, int index, T? inst) where T : class, IInstructionWithVariableOperand
{ {
Debug.Assert(list[index] == inst); Debug.Assert(list[index] == inst);
int indexToMove = list.Count - 1; int indexToMove = list.Count - 1;
@ -370,7 +370,7 @@ namespace ICSharpCode.Decompiler.IL
/// The field which was converted to a local variable. /// The field which was converted to a local variable.
/// Set when the variable is from a 'yield return' or 'async' state machine. /// Set when the variable is from a 'yield return' or 'async' state machine.
/// </summary> /// </summary>
public IField StateMachineField; public IField? StateMachineField;
public ILVariable(VariableKind kind, IType type, int? index = null) public ILVariable(VariableKind kind, IType type, int? index = null)
{ {
@ -398,7 +398,7 @@ namespace ICSharpCode.Decompiler.IL
CheckInvariant(); CheckInvariant();
} }
public override string ToString() public override string? ToString()
{ {
return Name; return Name;
} }
@ -472,7 +472,7 @@ namespace ICSharpCode.Decompiler.IL
if (CaptureScope != null) if (CaptureScope != null)
{ {
output.Write(" captured in "); output.Write(" captured in ");
output.WriteLocalReference(CaptureScope.EntryPoint.Label, CaptureScope); output.WriteLocalReference(CaptureScope.EntryPoint?.Label, CaptureScope);
} }
if (StateMachineField != null) if (StateMachineField != null)
{ {
@ -528,7 +528,7 @@ namespace ICSharpCode.Decompiler.IL
{ {
public static readonly ILVariableEqualityComparer Instance = new ILVariableEqualityComparer(); public static readonly ILVariableEqualityComparer Instance = new ILVariableEqualityComparer();
public bool Equals(ILVariable x, ILVariable y) public bool Equals(ILVariable? x, ILVariable? y)
{ {
if (x == y) if (x == y)
return true; return true;

3
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software

3
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software

7
ICSharpCode.Decompiler/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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -22,7 +23,7 @@ namespace ICSharpCode.Decompiler.IL
{ {
partial class Await partial class Await
{ {
public IMethod GetAwaiterMethod; public IMethod? GetAwaiterMethod;
public IMethod GetResultMethod; public IMethod? GetResultMethod;
} }
} }

5
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -214,5 +215,3 @@ namespace ICSharpCode.Decompiler.IL
} }
} }
} }

41
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -16,14 +17,13 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using ICSharpCode.Decompiler.IL.Transforms; using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.IL namespace ICSharpCode.Decompiler.IL
{ {
/// <summary> /// <summary>
@ -48,7 +48,7 @@ namespace ICSharpCode.Decompiler.IL
public readonly BlockKind Kind; public readonly BlockKind Kind;
public readonly InstructionCollection<ILInstruction> Instructions; public readonly InstructionCollection<ILInstruction> Instructions;
ILInstruction finalInstruction; ILInstruction finalInstruction = null!;
/// <summary> /// <summary>
/// For blocks in a block container, this field holds /// For blocks in a block container, this field holds
@ -125,7 +125,7 @@ namespace ICSharpCode.Decompiler.IL
{ {
var stloc = inst as StLoc; var stloc = inst as StLoc;
Debug.Assert(stloc != null, "Instructions in CallWithNamedArgs must be assignments"); 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.IsSingleDefinition && stloc.Variable.LoadCount == 1);
Debug.Assert(stloc.Variable.LoadInstructions.Single().Parent == finalInstruction); Debug.Assert(stloc.Variable.LoadInstructions.Single().Parent == finalInstruction);
} }
@ -140,22 +140,22 @@ namespace ICSharpCode.Decompiler.IL
case BlockKind.ArrayInitializer: case BlockKind.ArrayInitializer:
var final = finalInstruction as LdLoc; var final = finalInstruction as LdLoc;
Debug.Assert(final != null && final.Variable.IsSingleDefinition && final.Variable.Kind == VariableKind.InitializerTarget); Debug.Assert(final != null && final.Variable.IsSingleDefinition && final.Variable.Kind == VariableKind.InitializerTarget);
IType type = null; IType? type = null;
Debug.Assert(Instructions[0].MatchStLoc(final.Variable, out var init) && init.MatchNewArr(out type)); Debug.Assert(Instructions[0].MatchStLoc(final!.Variable, out var init) && init.MatchNewArr(out type));
for (int i = 1; i < Instructions.Count; i++) 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(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(target.MatchLdElema(out t, out ILInstruction? array) && type!.Equals(t));
Debug.Assert(array.MatchLdLoc(out ILVariable v) && v == final.Variable); Debug.Assert(array.MatchLdLoc(out ILVariable? v) && v == final.Variable);
} }
break; break;
case BlockKind.CollectionInitializer: case BlockKind.CollectionInitializer:
case BlockKind.ObjectInitializer: case BlockKind.ObjectInitializer:
var final2 = finalInstruction as LdLoc; var final2 = finalInstruction as LdLoc;
Debug.Assert(final2 != null); Debug.Assert(final2 != null);
var initVar2 = final2.Variable; var initVar2 = final2!.Variable;
Debug.Assert(initVar2.StoreCount == 1 && initVar2.Kind == VariableKind.InitializerTarget); 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); bool condition = Instructions[0].MatchStLoc(final2.Variable, out var init2);
Debug.Assert(condition); Debug.Assert(condition);
Debug.Assert(init2 is NewObj Debug.Assert(init2 is NewObj
@ -300,7 +300,7 @@ namespace ICSharpCode.Decompiler.IL
public void Remove() public void Remove()
{ {
Debug.Assert(ChildIndex > 0); Debug.Assert(ChildIndex > 0);
var container = (BlockContainer)Parent; var container = (BlockContainer)Parent!;
Debug.Assert(container.Blocks[ChildIndex] == this); Debug.Assert(container.Blocks[ChildIndex] == this);
container.Blocks.SwapRemoveAt(ChildIndex); container.Blocks.SwapRemoveAt(ChildIndex);
} }
@ -325,7 +325,7 @@ namespace ICSharpCode.Decompiler.IL
/// Gets the predecessor of the given instruction. /// Gets the predecessor of the given instruction.
/// Returns null if inst.Parent is not a block. /// Returns null if inst.Parent is not a block.
/// </summary> /// </summary>
public static ILInstruction GetPredecessor(ILInstruction inst) public static ILInstruction? GetPredecessor(ILInstruction inst)
{ {
if (inst.Parent is Block block && inst.ChildIndex > 0) 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. /// If inst is a block consisting of a single instruction, returns that instruction.
/// Otherwise, returns the input instruction. /// Otherwise, returns the input instruction.
/// </summary> /// </summary>
public static ILInstruction Unwrap(ILInstruction inst) [return: NotNullIfNotNull("inst")]
public static ILInstruction? Unwrap(ILInstruction? inst)
{ {
if (inst is Block block) if (inst is Block block)
{ {
@ -355,19 +356,19 @@ namespace ICSharpCode.Decompiler.IL
/// Gets the closest parent Block. /// Gets the closest parent Block.
/// Returns null, if the instruction is not a descendant of a Block. /// Returns null, if the instruction is not a descendant of a Block.
/// </summary> /// </summary>
public static Block FindClosestBlock(ILInstruction inst) public static Block? FindClosestBlock(ILInstruction? inst)
{ {
var curr = inst; var curr = inst;
while (curr != null) while (curr != null)
{ {
if (curr is Block) if (curr is Block b)
return (Block)curr; return b;
curr = curr.Parent; curr = curr.Parent;
} }
return null; 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; call = null;
value = null; value = null;
@ -385,7 +386,7 @@ namespace ICSharpCode.Decompiler.IL
return this.FinalInstruction.MatchLdLoc(tmp); 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; condition = null;
trueInst = null; trueInst = null;

32
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -19,11 +20,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using ICSharpCode.Decompiler.IL.Transforms; using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.IL namespace ICSharpCode.Decompiler.IL
{ {
/// <summary> /// <summary>
@ -57,13 +58,18 @@ namespace ICSharpCode.Decompiler.IL
} }
} }
Block entryPoint; Block? entryPoint;
/// <summary> /// <summary>
/// Gets the container's entry point. This is the first block in the Blocks collection. /// Gets the container's entry point. This is the first block in the Blocks collection.
/// </summary> /// </summary>
public Block EntryPoint { 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 { private set {
if (entryPoint != null && IsConnected) if (entryPoint != null && IsConnected)
entryPoint.IncomingEdgeCount--; entryPoint.IncomingEdgeCount--;
@ -102,7 +108,7 @@ namespace ICSharpCode.Decompiler.IL
protected internal override void InstructionCollectionUpdateComplete() protected internal override void InstructionCollectionUpdateComplete()
{ {
base.InstructionCollectionUpdateComplete(); base.InstructionCollectionUpdateComplete();
this.EntryPoint = this.Blocks.FirstOrDefault(); this.EntryPoint = this.Blocks.FirstOrDefault()!;
} }
protected override void Connected() protected override void Connected()
@ -174,7 +180,7 @@ namespace ICSharpCode.Decompiler.IL
return Blocks[index]; return Blocks[index];
} }
protected override void SetChild(int index, ILInstruction value) protected override void SetChild(int index, ILInstruction? value)
{ {
if (Blocks[index] != value) if (Blocks[index] != value)
throw new InvalidOperationException("Cannot replace blocks in BlockContainer"); throw new InvalidOperationException("Cannot replace blocks in BlockContainer");
@ -189,12 +195,12 @@ namespace ICSharpCode.Decompiler.IL
{ {
base.CheckInvariant(phase); base.CheckInvariant(phase);
Debug.Assert(Blocks.Count > 0 && EntryPoint == Blocks[0]); Debug.Assert(Blocks.Count > 0 && EntryPoint == Blocks[0]);
Debug.Assert(!IsConnected || EntryPoint?.IncomingEdgeCount >= 1); Debug.Assert(!IsConnected || EntryPoint.IncomingEdgeCount >= 1);
Debug.Assert(EntryPoint == null || Parent is ILFunction || !ILRangeIsEmpty); Debug.Assert(Parent is ILFunction || !ILRangeIsEmpty);
Debug.Assert(Blocks.All(b => b.HasFlag(InstructionFlags.EndPointUnreachable))); 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(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"); Debug.Assert(TopologicalSort(deleteUnreachableBlocks: true).Count == Blocks.Count, "Container should not have any unreachable blocks");
Block bodyStartBlock; Block? bodyStartBlock;
switch (Kind) switch (Kind)
{ {
case ContainerKind.Normal: case ContainerKind.Normal:
@ -319,7 +325,7 @@ namespace ICSharpCode.Decompiler.IL
Blocks.ReplaceList(newOrder); Blocks.ReplaceList(newOrder);
} }
public static BlockContainer FindClosestContainer(ILInstruction inst) public static BlockContainer? FindClosestContainer(ILInstruction? inst)
{ {
while (inst != null) while (inst != null)
{ {
@ -330,18 +336,18 @@ namespace ICSharpCode.Decompiler.IL
return null; return null;
} }
public static BlockContainer FindClosestSwitchContainer(ILInstruction inst) public static BlockContainer? FindClosestSwitchContainer(ILInstruction? inst)
{ {
while (inst != null) while (inst != null)
{ {
if (inst is BlockContainer bc && bc.entryPoint.Instructions.FirstOrDefault() is SwitchInstruction) if (inst is BlockContainer { Kind: ContainerKind.Switch } bc)
return bc; return bc;
inst = inst.Parent; inst = inst.Parent;
} }
return null; 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; condition = null;
bodyStartBlock = null; bodyStartBlock = null;

25
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -30,7 +31,7 @@ namespace ICSharpCode.Decompiler.IL
partial class Branch : SimpleInstruction, IBranchOrLeaveInstruction partial class Branch : SimpleInstruction, IBranchOrLeaveInstruction
{ {
readonly int targetILOffset; readonly int targetILOffset;
Block targetBlock; Block? targetBlock;
public Branch(int targetILOffset) : base(OpCode.Branch) public Branch(int targetILOffset) : base(OpCode.Branch)
{ {
@ -48,7 +49,11 @@ namespace ICSharpCode.Decompiler.IL
} }
public Block TargetBlock { 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 { set {
if (targetBlock != null && IsConnected) if (targetBlock != null && IsConnected)
targetBlock.IncomingEdgeCount--; targetBlock.IncomingEdgeCount--;
@ -62,7 +67,7 @@ namespace ICSharpCode.Decompiler.IL
/// Gets the BlockContainer that contains the target block. /// Gets the BlockContainer that contains the target block.
/// </summary> /// </summary>
public BlockContainer TargetContainer { public BlockContainer TargetContainer {
get { return (BlockContainer)targetBlock?.Parent; } get { return (BlockContainer)targetBlock?.Parent!; }
} }
protected override void Connected() 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) if (inst.Parent is TryFinally && inst.SlotInfo == TryFinally.TryBlockSlot)
return true; return true;
@ -107,9 +112,9 @@ namespace ICSharpCode.Decompiler.IL
base.CheckInvariant(phase); base.CheckInvariant(phase);
if (phase > ILPhase.InILReader) if (phase > ILPhase.InILReader)
{ {
Debug.Assert(targetBlock.Parent is BlockContainer); Debug.Assert(targetBlock?.Parent is BlockContainer);
Debug.Assert(this.IsDescendantOf(targetBlock.Parent)); Debug.Assert(this.IsDescendantOf(targetBlock!.Parent!));
Debug.Assert(targetBlock.Parent.Children[targetBlock.ChildIndex] == targetBlock); Debug.Assert(targetBlock!.Parent!.Children[targetBlock.ChildIndex] == targetBlock);
} }
} }
@ -118,7 +123,7 @@ namespace ICSharpCode.Decompiler.IL
WriteILRange(output, options); WriteILRange(output, options);
output.Write(OpCode); output.Write(OpCode);
output.Write(' '); output.Write(' ');
output.WriteLocalReference(TargetLabel, (object)targetBlock ?? TargetILOffset); output.WriteLocalReference(TargetLabel, (object?)targetBlock ?? TargetILOffset);
} }
} }

5
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -31,7 +32,7 @@ namespace ICSharpCode.Decompiler.IL
public static readonly SlotInfo FunctionPointerSlot = new SlotInfo("FunctionPointer", canInlineInto: true); public static readonly SlotInfo FunctionPointerSlot = new SlotInfo("FunctionPointer", canInlineInto: true);
public static readonly SlotInfo ArgumentSlot = new SlotInfo("Argument", canInlineInto: true, isCollection: true); public static readonly SlotInfo ArgumentSlot = new SlotInfo("Argument", canInlineInto: true, isCollection: true);
ILInstruction functionPointer; ILInstruction functionPointer = null!;
public readonly InstructionCollection<ILInstruction> Arguments; public readonly InstructionCollection<ILInstruction> Arguments;
public bool IsInstance { get; } public bool IsInstance { get; }
public bool HasExplicitThis { get; } public bool HasExplicitThis { get; }

15
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -19,7 +20,6 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.IL namespace ICSharpCode.Decompiler.IL
@ -52,7 +52,7 @@ namespace ICSharpCode.Decompiler.IL
/// Gets/Sets the type specified in the 'constrained.' prefix. /// Gets/Sets the type specified in the 'constrained.' prefix.
/// Returns null if no 'constrained.' prefix exists for this call. /// Returns null if no 'constrained.' prefix exists for this call.
/// </summary> /// </summary>
public IType ConstrainedTo; public IType? ConstrainedTo;
/// <summary> /// <summary>
/// Gets whether the IL stack was empty at the point of this call. /// 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) protected CallInstruction(OpCode opCode, IMethod method) : base(opCode)
{ {
Debug.Assert(method != null); this.Method = method ?? throw new ArgumentNullException(nameof(method));
this.Method = method;
this.Arguments = new InstructionCollection<ILInstruction>(this, 0); this.Arguments = new InstructionCollection<ILInstruction>(this, 0);
} }
@ -78,7 +77,7 @@ namespace ICSharpCode.Decompiler.IL
/// Gets the parameter for the argument with the specified index. /// Gets the parameter for the argument with the specified index.
/// Returns null for the <c>this</c> parameter. /// Returns null for the <c>this</c> parameter.
/// </summary> /// </summary>
public IParameter GetParameter(int argumentIndex) public IParameter? GetParameter(int argumentIndex)
{ {
int firstParamIndex = (Method.IsStatic || OpCode == OpCode.NewObj) ? 0 : 1; int firstParamIndex = (Method.IsStatic || OpCode == OpCode.NewObj) ? 0 : 1;
if (argumentIndex < firstParamIndex) if (argumentIndex < firstParamIndex)
@ -160,9 +159,9 @@ namespace ICSharpCode.Decompiler.IL
output.Write(')'); 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 return o != null && this.OpCode == o.OpCode && this.Method.Equals(o.Method) && this.IsTail == o.IsTail
&& object.Equals(this.ConstrainedTo, o.ConstrainedTo) && object.Equals(this.ConstrainedTo, o.ConstrainedTo)
&& Patterns.ListMatch.DoMatch(this.Arguments, o.Arguments, ref match); && Patterns.ListMatch.DoMatch(this.Arguments, o.Arguments, ref match);

6
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -21,7 +22,6 @@ using System.Diagnostics;
using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.IL namespace ICSharpCode.Decompiler.IL
{ {
@ -231,5 +231,3 @@ namespace ICSharpCode.Decompiler.IL
} }
} }
} }

5
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -172,7 +173,7 @@ namespace ICSharpCode.Decompiler.IL
/// <summary> /// <summary>
/// Gets whether the specific binary instruction is compatible with a compound operation on the specified type. /// Gets whether the specific binary instruction is compatible with a compound operation on the specified type.
/// </summary> /// </summary>
internal static bool IsBinaryCompatibleWithType(BinaryNumericInstruction binary, IType type, DecompilerSettings settings) internal static bool IsBinaryCompatibleWithType(BinaryNumericInstruction binary, IType type, DecompilerSettings? settings)
{ {
if (binary.IsLifted) if (binary.IsLifted)
{ {

3
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software

9
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -47,9 +48,9 @@ namespace ICSharpCode.Decompiler.IL
output.Write(')'); 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) if (inst.Parent is MatchInstruction match && inst != match.TestedOperand)
return match; return match;
@ -61,7 +62,7 @@ namespace ICSharpCode.Decompiler.IL
{ {
var matchInst = FindMatch(); var matchInst = FindMatch();
Debug.Assert(matchInst != null && (matchInst.IsDeconstructCall || matchInst.IsDeconstructTuple)); 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); var outParamType = matchInst.GetDeconstructResultType(this.Index);
Debug.Assert(outParamType.GetStackType() == ResultType); Debug.Assert(outParamType.GetStackType() == ResultType);
} }

3
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software

41
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -56,7 +57,7 @@ namespace ICSharpCode.Decompiler.IL
public struct CSharpArgumentInfo public struct CSharpArgumentInfo
{ {
public string Name { get; set; } public string? Name { get; set; }
public CSharpArgumentInfoFlags Flags { get; set; } public CSharpArgumentInfoFlags Flags { get; set; }
public IType CompileTimeType { get; set; } public IType CompileTimeType { get; set; }
@ -66,9 +67,9 @@ namespace ICSharpCode.Decompiler.IL
partial class DynamicInstruction partial class DynamicInstruction
{ {
public CSharpBinderFlags BinderFlags { get; } 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) : base(opCode)
{ {
BinderFlags = binderFlags; BinderFlags = binderFlags;
@ -141,7 +142,7 @@ namespace ICSharpCode.Decompiler.IL
output.Write(')'); 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) : base(OpCode.DynamicConvertInstruction, binderFlags, context)
{ {
Type = type; Type = type;
@ -171,7 +172,7 @@ namespace ICSharpCode.Decompiler.IL
public IReadOnlyList<IType> TypeArguments { get; } public IReadOnlyList<IType> TypeArguments { get; }
public IReadOnlyList<CSharpArgumentInfo> ArgumentInfo { get; } public IReadOnlyList<CSharpArgumentInfo> 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) : base(OpCode.DynamicInvokeMemberInstruction, binderFlags, context)
{ {
Name = name; Name = name;
@ -216,10 +217,10 @@ namespace ICSharpCode.Decompiler.IL
partial class DynamicGetMemberInstruction partial class DynamicGetMemberInstruction
{ {
public string Name { get; } public string? Name { get; }
public CSharpArgumentInfo TargetArgumentInfo { 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) : base(OpCode.DynamicGetMemberInstruction, binderFlags, context)
{ {
Name = name; Name = name;
@ -249,11 +250,11 @@ namespace ICSharpCode.Decompiler.IL
partial class DynamicSetMemberInstruction partial class DynamicSetMemberInstruction
{ {
public string Name { get; } public string? Name { get; }
public CSharpArgumentInfo TargetArgumentInfo { get; } public CSharpArgumentInfo TargetArgumentInfo { get; }
public CSharpArgumentInfo ValueArgumentInfo { 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) : base(OpCode.DynamicSetMemberInstruction, binderFlags, context)
{ {
Name = name; Name = name;
@ -293,7 +294,7 @@ namespace ICSharpCode.Decompiler.IL
{ {
public IReadOnlyList<CSharpArgumentInfo> ArgumentInfo { get; } public IReadOnlyList<CSharpArgumentInfo> 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) : base(OpCode.DynamicGetIndexInstruction, binderFlags, context)
{ {
ArgumentInfo = argumentInfo; ArgumentInfo = argumentInfo;
@ -325,7 +326,7 @@ namespace ICSharpCode.Decompiler.IL
{ {
public IReadOnlyList<CSharpArgumentInfo> ArgumentInfo { get; } public IReadOnlyList<CSharpArgumentInfo> 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) : base(OpCode.DynamicSetIndexInstruction, binderFlags, context)
{ {
ArgumentInfo = argumentInfo; ArgumentInfo = argumentInfo;
@ -355,11 +356,11 @@ namespace ICSharpCode.Decompiler.IL
partial class DynamicInvokeConstructorInstruction partial class DynamicInvokeConstructorInstruction
{ {
readonly IType resultType; readonly IType? resultType;
public IReadOnlyList<CSharpArgumentInfo> ArgumentInfo { get; } public IReadOnlyList<CSharpArgumentInfo> 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) : base(OpCode.DynamicInvokeConstructorInstruction, binderFlags, context)
{ {
ArgumentInfo = argumentInfo; ArgumentInfo = argumentInfo;
@ -395,7 +396,7 @@ namespace ICSharpCode.Decompiler.IL
public CSharpArgumentInfo RightArgumentInfo { get; } public CSharpArgumentInfo RightArgumentInfo { get; }
public ExpressionType Operation { 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) : base(OpCode.DynamicBinaryOperatorInstruction, binderFlags, context)
{ {
Operation = operation; Operation = operation;
@ -437,7 +438,7 @@ namespace ICSharpCode.Decompiler.IL
public CSharpArgumentInfo RightArgumentInfo { get; } public CSharpArgumentInfo RightArgumentInfo { get; }
public ExpressionType Operation { 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) : base(OpCode.DynamicLogicOperatorInstruction, binderFlags, context)
{ {
Operation = operation; Operation = operation;
@ -486,7 +487,7 @@ namespace ICSharpCode.Decompiler.IL
public CSharpArgumentInfo OperandArgumentInfo { get; } public CSharpArgumentInfo OperandArgumentInfo { get; }
public ExpressionType Operation { 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) : base(OpCode.DynamicUnaryOperatorInstruction, binderFlags, context)
{ {
Operation = operation; Operation = operation;
@ -533,7 +534,7 @@ namespace ICSharpCode.Decompiler.IL
{ {
public IReadOnlyList<CSharpArgumentInfo> ArgumentInfo { get; } public IReadOnlyList<CSharpArgumentInfo> 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) : base(OpCode.DynamicInvokeInstruction, binderFlags, context)
{ {
ArgumentInfo = argumentInfo; ArgumentInfo = argumentInfo;
@ -562,9 +563,9 @@ namespace ICSharpCode.Decompiler.IL
partial class DynamicIsEventInstruction 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) : base(OpCode.DynamicIsEventInstruction, binderFlags, context)
{ {
Name = name; Name = name;

3
ICSharpCode.Decompiler/IL/Instructions/ExpressionTreeCast.cs

@ -1,4 +1,5 @@
using System; #nullable enable
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;

30
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -18,7 +19,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
@ -35,7 +35,7 @@ namespace ICSharpCode.Decompiler.IL
/// May be null for functions that were not constructed from metadata, /// May be null for functions that were not constructed from metadata,
/// e.g., expression trees. /// e.g., expression trees.
/// </summary> /// </summary>
public readonly IMethod Method; public readonly IMethod? Method;
/// <summary> /// <summary>
/// Gets the generic context of this function. /// 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. /// has no effect, as the name should not be used in the final AST construction.
/// </para> /// </para>
/// </summary> /// </summary>
public string Name; public string? Name;
/// <summary> /// <summary>
/// Size of the IL code in this function. /// 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. /// Gets the scope in which the local function is declared.
/// Returns null, if this is not a local function. /// Returns null, if this is not a local function.
/// </summary> /// </summary>
public BlockContainer DeclarationScope { get; internal set; } public BlockContainer? DeclarationScope { get; internal set; }
/// <summary> /// <summary>
/// Gets the set of captured variables by this ILFunction. /// 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. /// 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. /// If the async method returns Task or void, this field stores void.
/// </summary> /// </summary>
public IType AsyncReturnType; public IType? AsyncReturnType;
/// <summary> /// <summary>
/// If this function is an iterator/async, this field stores the compiler-generated MoveNext() method. /// If this function is an iterator/async, this field stores the compiler-generated MoveNext() method.
/// </summary> /// </summary>
public IMethod MoveNextMethod; public IMethod? MoveNextMethod;
/// <summary> /// <summary>
/// If this function is a local function, this field stores the reduced version of the function. /// If this function is a local function, this field stores the reduced version of the function.
/// </summary> /// </summary>
internal TypeSystem.Implementation.LocalFunctionMethod ReducedMethod; internal TypeSystem.Implementation.LocalFunctionMethod? ReducedMethod;
public DebugInfo.AsyncDebugInfo AsyncDebugInfo; public DebugInfo.AsyncDebugInfo AsyncDebugInfo;
@ -131,8 +131,10 @@ namespace ICSharpCode.Decompiler.IL
get { get {
if (ctorCallStart == int.MinValue) if (ctorCallStart == int.MinValue)
{ {
if (!this.Method.IsConstructor || this.Method.IsStatic) if (this.Method == null || !this.Method.IsConstructor || this.Method.IsStatic)
{
ctorCallStart = -1; ctorCallStart = -1;
}
else else
{ {
ctorCallStart = this.Descendants.FirstOrDefault(d => d is CallInstruction call && !(call is NewObj) 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. /// T is the delegate type that matches the signature of this method.
/// Otherwise this must be null. /// Otherwise this must be null.
/// </summary> /// </summary>
public IType DelegateType; public IType? DelegateType;
ILFunctionKind kind; ILFunctionKind kind;
@ -181,7 +183,7 @@ namespace ICSharpCode.Decompiler.IL
/// where the stack is empty, nop instructions, and the instruction following /// where the stack is empty, nop instructions, and the instruction following
/// a call instruction /// a call instruction
/// </summary> /// </summary>
public List<int> SequencePointCandidates { get; set; } public List<int>? SequencePointCandidates { get; set; }
/// <summary> /// <summary>
/// Constructs a new ILFunction from the given metadata and with the given ILAst body. /// Constructs a new ILFunction from the given metadata and with the given ILAst body.
@ -408,18 +410,18 @@ namespace ICSharpCode.Decompiler.IL
int helperVariableCount; 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); 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()); var type = Method.Compilation.FindType(stackType.ToKnownTypeCode());
return RegisterVariable(kind, type, stackType, name); 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); var variable = new ILVariable(kind, type, stackType);
if (string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(name))

2
ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs

@ -60,7 +60,7 @@ namespace ICSharpCode.Decompiler.IL
this.OpCode = opCode; this.OpCode = opCode;
} }
protected void ValidateChild(ILInstruction inst) protected void ValidateChild(ILInstruction? inst)
{ {
if (inst == null) if (inst == null)
throw new ArgumentNullException(nameof(inst)); throw new ArgumentNullException(nameof(inst));

5
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -128,7 +129,7 @@ namespace ICSharpCode.Decompiler.IL
{ {
// However, remove unused this-parameters of delegates, expression trees, etc. // However, remove unused this-parameters of delegates, expression trees, etc.
// These will be replaced with the top-level function's this-parameter. // 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 true;
return false; return false;
} }

9
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -35,7 +36,7 @@ namespace ICSharpCode.Decompiler.IL
/// </remarks> /// </remarks>
partial class IfInstruction : ILInstruction 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.Condition = condition;
this.TrueInst = trueInst; this.TrueInst = trueInst;
@ -47,7 +48,7 @@ namespace ICSharpCode.Decompiler.IL
return new IfInstruction(lhs, rhs, new LdcI4(0)); 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); return new IfInstruction(lhs, new LdcI4(1), rhs);
} }
@ -126,7 +127,7 @@ namespace ICSharpCode.Decompiler.IL
if (slot == IfInstruction.ConditionSlot) if (slot == IfInstruction.ConditionSlot)
return true; return true;
if (slot == IfInstruction.TrueInstSlot || slot == IfInstruction.FalseInstSlot || slot == NullCoalescingInstruction.FallbackInstSlot) 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 (inst.Parent is Comp comp)
{ {
if (comp.Left == inst && comp.Right.MatchLdcI4(0)) if (comp.Left == inst && comp.Right.MatchLdcI4(0))

3
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software

3
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software

13
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -32,9 +33,9 @@ namespace ICSharpCode.Decompiler.IL
/// </remarks> /// </remarks>
partial class Leave : ILInstruction, IBranchOrLeaveInstruction 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', // Note: ILReader will create Leave instructions with targetContainer==null to represent 'endfinally',
// the targetContainer will then be filled in by BlockBuilder // the targetContainer will then be filled in by BlockBuilder
@ -54,7 +55,7 @@ namespace ICSharpCode.Decompiler.IL
} }
public BlockContainer TargetContainer { public BlockContainer TargetContainer {
get { return targetContainer; } get { return targetContainer!; }
set { set {
if (targetContainer != null && IsConnected) if (targetContainer != null && IsConnected)
targetContainer.LeaveCount--; targetContainer.LeaveCount--;
@ -109,8 +110,8 @@ namespace ICSharpCode.Decompiler.IL
internal override void CheckInvariant(ILPhase phase) internal override void CheckInvariant(ILPhase phase)
{ {
base.CheckInvariant(phase); base.CheckInvariant(phase);
Debug.Assert(phase <= ILPhase.InILReader || this.IsDescendantOf(targetContainer)); 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 || phase == ILPhase.InAsyncAwait || value.ResultType == targetContainer!.ResultType);
} }
public override void WriteTo(ITextOutput output, ILAstWritingOptions options) public override void WriteTo(ITextOutput output, ILAstWritingOptions options)

3
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software

3
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software

14
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -18,10 +19,9 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Diagnostics.CodeAnalysis;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.IL namespace ICSharpCode.Decompiler.IL
{ {
partial class MatchInstruction : ILInstruction 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) : this(variable, method: null, testedOperand)
{ {
} }
@ -118,7 +118,7 @@ namespace ICSharpCode.Decompiler.IL
/// (even if the pattern fails to match!). /// (even if the pattern fails to match!).
/// The pattern matching instruction evaluates to 1 (as I4) if the pattern matches, or 0 otherwise. /// The pattern matching instruction evaluates to 1 (as I4) if the pattern matches, or 0 otherwise.
/// </summary> /// </summary>
public static bool IsPatternMatch(ILInstruction inst, out ILInstruction testedOperand) public static bool IsPatternMatch(ILInstruction? inst, [NotNullWhen(true)] out ILInstruction? testedOperand)
{ {
switch (inst) switch (inst)
{ {
@ -185,8 +185,8 @@ namespace ICSharpCode.Decompiler.IL
Debug.Assert(SubPatterns.Count >= NumPositionalPatterns); Debug.Assert(SubPatterns.Count >= NumPositionalPatterns);
foreach (var subPattern in SubPatterns) foreach (var subPattern in SubPatterns)
{ {
if (!IsPatternMatch(subPattern, out ILInstruction operand)) if (!IsPatternMatch(subPattern, out ILInstruction? operand))
Debug.Fail("Sub-Pattern must be a valid pattern"); throw new InvalidOperationException("Sub-Pattern must be a valid pattern");
// the first child is TestedOperand // the first child is TestedOperand
int subPatternIndex = subPattern.ChildIndex - 1; int subPatternIndex = subPattern.ChildIndex - 1;
if (subPatternIndex < NumPositionalPatterns) if (subPatternIndex < NumPositionalPatterns)

3
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software

3
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software

3
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software

75
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -16,8 +17,9 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using ICSharpCode.Decompiler.TypeSystem; using System.Diagnostics.CodeAnalysis;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.IL namespace ICSharpCode.Decompiler.IL
{ {
partial class ILInstruction partial class ILInstruction
@ -73,13 +75,13 @@ namespace ICSharpCode.Decompiler.IL
return MatchLdcI(out long v) && v == val; return MatchLdcI(out long v) && v == val;
} }
public bool MatchLdLoc(ILVariable variable) public bool MatchLdLoc(ILVariable? variable)
{ {
var inst = this as LdLoc; var inst = this as LdLoc;
return inst != null && inst.Variable == variable; return inst != null && inst.Variable == variable;
} }
public bool MatchLdLoca(ILVariable variable) public bool MatchLdLoca(ILVariable? variable)
{ {
var inst = this as LdLoca; var inst = this as LdLoca;
return inst != null && inst.Variable == variable; return inst != null && inst.Variable == variable;
@ -88,7 +90,7 @@ namespace ICSharpCode.Decompiler.IL
/// <summary> /// <summary>
/// Matches either ldloc (if the variable is a reference type), or ldloca (otherwise). /// Matches either ldloc (if the variable is a reference type), or ldloca (otherwise).
/// </summary> /// </summary>
public bool MatchLdLocRef(ILVariable variable) public bool MatchLdLocRef(ILVariable? variable)
{ {
return MatchLdLocRef(out var v) && v == variable; return MatchLdLocRef(out var v) && v == variable;
} }
@ -96,7 +98,7 @@ namespace ICSharpCode.Decompiler.IL
/// <summary> /// <summary>
/// Matches either ldloc (if the variable is a reference type), or ldloca (otherwise). /// Matches either ldloc (if the variable is a reference type), or ldloca (otherwise).
/// </summary> /// </summary>
public bool MatchLdLocRef(out ILVariable variable) public bool MatchLdLocRef([NotNullWhen(true)] out ILVariable? variable)
{ {
switch (this) switch (this)
{ {
@ -118,7 +120,7 @@ namespace ICSharpCode.Decompiler.IL
return inst != null && inst.Variable.Kind == VariableKind.Parameter && inst.Variable.Index < 0; 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; var inst = this as StLoc;
if (inst != null) if (inst != null)
@ -130,7 +132,7 @@ namespace ICSharpCode.Decompiler.IL
return false; 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; var inst = this as StLoc;
if (inst != null && inst.Variable == variable) if (inst != null && inst.Variable == variable)
@ -142,7 +144,7 @@ namespace ICSharpCode.Decompiler.IL
return false; 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; var inst = this as LdLen;
if (inst != null && inst.ResultType == type) if (inst != null && inst.ResultType == type)
@ -154,7 +156,7 @@ namespace ICSharpCode.Decompiler.IL
return false; return false;
} }
public bool MatchReturn(out ILInstruction value) public bool MatchReturn([NotNullWhen(true)] out ILInstruction? value)
{ {
var inst = this as Leave; var inst = this as Leave;
if (inst != null && inst.IsLeavingFunction) if (inst != null && inst.IsLeavingFunction)
@ -166,7 +168,7 @@ namespace ICSharpCode.Decompiler.IL
return false; return false;
} }
public bool MatchBranch(out Block targetBlock) public bool MatchBranch([NotNullWhen(true)] out Block? targetBlock)
{ {
var inst = this as Branch; var inst = this as Branch;
if (inst != null) if (inst != null)
@ -178,13 +180,13 @@ namespace ICSharpCode.Decompiler.IL
return false; return false;
} }
public bool MatchBranch(Block targetBlock) public bool MatchBranch(Block? targetBlock)
{ {
var inst = this as Branch; var inst = this as Branch;
return inst != null && inst.TargetBlock == targetBlock; 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; var inst = this as Leave;
if (inst != null) if (inst != null)
@ -198,7 +200,7 @@ namespace ICSharpCode.Decompiler.IL
return false; 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; var inst = this as Leave;
if (inst != null && targetContainer == inst.TargetContainer) if (inst != null && targetContainer == inst.TargetContainer)
@ -210,7 +212,7 @@ namespace ICSharpCode.Decompiler.IL
return false; return false;
} }
public bool MatchLeave(out BlockContainer targetContainer) public bool MatchLeave([NotNullWhen(true)] out BlockContainer? targetContainer)
{ {
var inst = this as Leave; var inst = this as Leave;
if (inst != null && inst.Value.MatchNop()) if (inst != null && inst.Value.MatchNop())
@ -222,16 +224,15 @@ namespace ICSharpCode.Decompiler.IL
return false; return false;
} }
public bool MatchLeave(BlockContainer targetContainer) public bool MatchLeave(BlockContainer? targetContainer)
{ {
var inst = this as Leave; var inst = this as Leave;
return inst != null && inst.TargetContainer == targetContainer && inst.Value.MatchNop(); 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 (this is IfInstruction inst)
if (inst != null)
{ {
condition = inst.Condition; condition = inst.Condition;
trueInst = inst.TrueInst; trueInst = inst.TrueInst;
@ -244,7 +245,7 @@ namespace ICSharpCode.Decompiler.IL
return false; 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)) if (MatchIfInstruction(out condition, out trueInst, out falseInst))
{ {
@ -252,7 +253,7 @@ namespace ICSharpCode.Decompiler.IL
while (condition.MatchLogicNot(out var arg)) while (condition.MatchLogicNot(out var arg))
{ {
condition = arg; condition = arg;
ILInstruction tmp = trueInst; ILInstruction? tmp = trueInst;
trueInst = falseInst; trueInst = falseInst;
falseInst = tmp; falseInst = tmp;
} }
@ -264,7 +265,7 @@ namespace ICSharpCode.Decompiler.IL
/// <summary> /// <summary>
/// Matches an if instruction where the false instruction is a nop. /// Matches an if instruction where the false instruction is a nop.
/// </summary> /// </summary>
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; var inst = this as IfInstruction;
if (inst != null && inst.FalseInst.MatchNop()) if (inst != null && inst.FalseInst.MatchNop())
@ -283,7 +284,7 @@ namespace ICSharpCode.Decompiler.IL
/// Note: unlike C# '&amp;&amp;', this instruction is not limited to booleans, /// Note: unlike C# '&amp;&amp;', this instruction is not limited to booleans,
/// but allows passing through arbitrary I4 values on the rhs (but not on the lhs). /// but allows passing through arbitrary I4 values on the rhs (but not on the lhs).
/// </summary> /// </summary>
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; var inst = this as IfInstruction;
if (inst != null && inst.FalseInst.MatchLdcI4(0)) 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, /// 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). /// but allows passing through arbitrary I4 values on the rhs (but not on the lhs).
/// </summary> /// </summary>
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; var inst = this as IfInstruction;
if (inst != null && inst.TrueInst.MatchLdcI4(1)) if (inst != null && inst.TrueInst.MatchLdcI4(1))
@ -319,7 +320,7 @@ namespace ICSharpCode.Decompiler.IL
/// <summary> /// <summary>
/// Matches an logical negation. /// Matches an logical negation.
/// </summary> /// </summary>
public bool MatchLogicNot(out ILInstruction arg) public bool MatchLogicNot([NotNullWhen(true)] out ILInstruction? arg)
{ {
if (this is Comp comp && comp.Kind == ComparisonKind.Equality if (this is Comp comp && comp.Kind == ComparisonKind.Equality
&& comp.LiftingKind == ComparisonLiftingKind.None && comp.LiftingKind == ComparisonLiftingKind.None
@ -332,7 +333,7 @@ namespace ICSharpCode.Decompiler.IL
return false; return false;
} }
public bool MatchTryCatchHandler(out ILVariable variable) public bool MatchTryCatchHandler([NotNullWhen(true)] out ILVariable? variable)
{ {
var inst = this as TryCatchHandler; var inst = this as TryCatchHandler;
if (inst != null) if (inst != null)
@ -347,7 +348,7 @@ namespace ICSharpCode.Decompiler.IL
/// <summary> /// <summary>
/// Matches comp(left == right) or logic.not(comp(left != right)). /// Matches comp(left == right) or logic.not(comp(left != right)).
/// </summary> /// </summary>
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; ILInstruction thisInst = this;
var compKind = ComparisonKind.Equality; var compKind = ComparisonKind.Equality;
@ -376,7 +377,7 @@ namespace ICSharpCode.Decompiler.IL
/// <summary> /// <summary>
/// Matches 'comp(arg == ldnull)' /// Matches 'comp(arg == ldnull)'
/// </summary> /// </summary>
public bool MatchCompEqualsNull(out ILInstruction arg) public bool MatchCompEqualsNull([NotNullWhen(true)] out ILInstruction? arg)
{ {
if (!MatchCompEquals(out var left, out var right)) if (!MatchCompEquals(out var left, out var right))
{ {
@ -403,7 +404,7 @@ namespace ICSharpCode.Decompiler.IL
/// <summary> /// <summary>
/// Matches 'comp(arg != ldnull)' /// Matches 'comp(arg != ldnull)'
/// </summary> /// </summary>
public bool MatchCompNotEqualsNull(out ILInstruction arg) public bool MatchCompNotEqualsNull([NotNullWhen(true)] out ILInstruction? arg)
{ {
if (!MatchCompNotEquals(out var left, out var right)) if (!MatchCompNotEquals(out var left, out var right))
{ {
@ -430,7 +431,7 @@ namespace ICSharpCode.Decompiler.IL
/// <summary> /// <summary>
/// Matches comp(left != right) or logic.not(comp(left == right)). /// Matches comp(left != right) or logic.not(comp(left == right)).
/// </summary> /// </summary>
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; ILInstruction thisInst = this;
var compKind = ComparisonKind.Inequality; 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) 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; 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) 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; return false;
} }
public bool MatchLdsFld(IField field) public bool MatchLdsFld(IField? field)
{ {
return MatchLdsFld(out var f) && f.Equals(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) 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; 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) 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; 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; var op = this as BinaryNumericInstruction;
if (op != null && op.Operator == @operator) if (op != null && op.Operator == @operator)
@ -536,7 +537,7 @@ namespace ICSharpCode.Decompiler.IL
return false; 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; var op = this as BinaryNumericInstruction;
if (op != null) if (op != null)

13
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -40,7 +41,7 @@ namespace ICSharpCode.Decompiler.IL
partial class Nop partial class Nop
{ {
public string Comment; public string? Comment;
public NopKind Kind; public NopKind Kind;
@ -61,10 +62,10 @@ namespace ICSharpCode.Decompiler.IL
partial class InvalidBranch : SimpleInstruction partial class InvalidBranch : SimpleInstruction
{ {
public string Message; public string? Message;
public StackType ExpectedResultType = StackType.Void; public StackType ExpectedResultType = StackType.Void;
public InvalidBranch(string message) : this() public InvalidBranch(string? message) : this()
{ {
this.Message = message; this.Message = message;
} }
@ -88,10 +89,10 @@ namespace ICSharpCode.Decompiler.IL
partial class InvalidExpression : SimpleInstruction partial class InvalidExpression : SimpleInstruction
{ {
public string Message; public string? Message;
public StackType ExpectedResultType = StackType.Unknown; public StackType ExpectedResultType = StackType.Unknown;
public InvalidExpression(string message) : this() public InvalidExpression(string? message) : this()
{ {
this.Message = message; this.Message = message;
} }

7
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -38,8 +39,8 @@ namespace ICSharpCode.Decompiler.IL
internal override void CheckInvariant(ILPhase phase) internal override void CheckInvariant(ILPhase phase)
{ {
base.CheckInvariant(phase); base.CheckInvariant(phase);
Debug.Assert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function)); 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 || variable.Function!.Variables[variable.IndexInFunction] == variable);
Debug.Assert(value.ResultType == variable.StackType); Debug.Assert(value.ResultType == variable.StackType);
} }
} }

13
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -23,23 +24,23 @@ namespace ICSharpCode.Decompiler.IL
{ {
partial class StringToInt 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) : base(OpCode.StringToInt)
{ {
this.Argument = argument; this.Argument = argument;
this.Map = map; this.Map = map;
} }
public StringToInt(ILInstruction argument, string[] map) public StringToInt(ILInstruction? argument, string?[] map)
: this(argument, ArrayToDictionary(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++) for (int i = 0; i < map.Length; i++)
{ {
dict.Add((map[i], i)); dict.Add((map[i], i));

4
ICSharpCode.Decompiler/IL/Instructions/SwitchInstruction.cs

@ -1,3 +1,4 @@
#nullable enable
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team // Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this // Permission is hereby granted, free of charge, to any person obtaining a copy of this
@ -16,7 +17,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
@ -49,7 +49,7 @@ namespace ICSharpCode.Decompiler.IL
this.Sections = new InstructionCollection<SwitchSection>(this, 1); this.Sections = new InstructionCollection<SwitchSection>(this, 1);
} }
ILInstruction value; ILInstruction value = null!;
public ILInstruction Value { public ILInstruction Value {
get { return this.value; } get { return this.value; }
set { set {

11
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -33,7 +34,7 @@ namespace ICSharpCode.Decompiler.IL
this.TryBlock = tryBlock; this.TryBlock = tryBlock;
} }
ILInstruction tryBlock; ILInstruction tryBlock = null!;
public ILInstruction TryBlock { public ILInstruction TryBlock {
get { return this.tryBlock; } get { return this.tryBlock; }
set { set {
@ -144,7 +145,7 @@ namespace ICSharpCode.Decompiler.IL
base.CheckInvariant(phase); base.CheckInvariant(phase);
Debug.Assert(Parent is TryCatch); Debug.Assert(Parent is TryCatch);
Debug.Assert(filter.ResultType == StackType.I4); Debug.Assert(filter.ResultType == StackType.I4);
Debug.Assert(this.IsDescendantOf(variable.Function)); Debug.Assert(this.IsDescendantOf(variable.Function!));
} }
public override StackType ResultType { public override StackType ResultType {
@ -202,7 +203,7 @@ namespace ICSharpCode.Decompiler.IL
this.FinallyBlock = finallyBlock; this.FinallyBlock = finallyBlock;
} }
ILInstruction finallyBlock; ILInstruction finallyBlock = null!;
public ILInstruction FinallyBlock { public ILInstruction FinallyBlock {
get { return this.finallyBlock; } get { return this.finallyBlock; }
set { set {
@ -299,7 +300,7 @@ namespace ICSharpCode.Decompiler.IL
this.FaultBlock = faultBlock; this.FaultBlock = faultBlock;
} }
ILInstruction faultBlock; ILInstruction faultBlock = null!;
public ILInstruction FaultBlock { public ILInstruction FaultBlock {
get { return this.faultBlock; } get { return this.faultBlock; }
set { set {

3
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software

3
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software

16
ICSharpCode.Decompiler/IL/Patterns/AnyNode.cs

@ -1,8 +1,5 @@
using System; #nullable enable
using System.Collections.Generic; using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ICSharpCode.Decompiler.IL.Patterns namespace ICSharpCode.Decompiler.IL.Patterns
{ {
@ -37,19 +34,20 @@ namespace ICSharpCode.Decompiler.IL.Patterns
partial class AnyNode : PatternInstruction partial class AnyNode : PatternInstruction
{ {
CaptureGroup group; CaptureGroup? group;
public AnyNode(CaptureGroup group = null) public AnyNode(CaptureGroup? group = null)
: base(OpCode.AnyNode) : base(OpCode.AnyNode)
{ {
this.group = group; 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) if (other == null)
return false; return false;
match.Add(group, other); if (group != null)
match.Add(group, other);
return true; return true;
} }
} }

13
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -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 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 /// If the method returns false, the match object remains in a partially-updated state and needs to be restored
/// before it can be reused.</returns> /// before it can be reused.</returns>
internal static bool DoMatch(IReadOnlyList<ILInstruction> patterns, IReadOnlyList<ILInstruction> syntaxList, ref Match match) internal static bool DoMatch(IReadOnlyList<ILInstruction> patterns, IReadOnlyList<ILInstruction?> syntaxList, ref Match match)
{ {
ListMatch listMatch = new ListMatch(syntaxList); ListMatch listMatch = new ListMatch(syntaxList);
do do
@ -107,14 +108,14 @@ namespace ICSharpCode.Decompiler.IL.Patterns
/// <summary> /// <summary>
/// The syntax list we are matching against. /// The syntax list we are matching against.
/// </summary> /// </summary>
internal readonly IReadOnlyList<ILInstruction> SyntaxList; internal readonly IReadOnlyList<ILInstruction?> SyntaxList;
/// <summary> /// <summary>
/// The current index in the syntax list. /// The current index in the syntax list.
/// </summary> /// </summary>
internal int SyntaxIndex; internal int SyntaxIndex;
ListMatch(IReadOnlyList<ILInstruction> syntaxList) ListMatch(IReadOnlyList<ILInstruction?> syntaxList)
{ {
this.SyntaxList = syntaxList; this.SyntaxList = syntaxList;
this.SyntaxIndex = 0; this.SyntaxIndex = 0;
@ -122,8 +123,8 @@ namespace ICSharpCode.Decompiler.IL.Patterns
this.restoreStack = null; this.restoreStack = null;
} }
List<SavePoint> backtrackingStack; List<SavePoint>? backtrackingStack;
Stack<int> restoreStack; Stack<int>? restoreStack;
void AddSavePoint(SavePoint savepoint) void AddSavePoint(SavePoint savepoint)
{ {

5
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -33,7 +34,7 @@ namespace ICSharpCode.Decompiler.IL.Patterns
{ {
static readonly List<KeyValuePair<CaptureGroup, ILInstruction>> emptyResults = new List<KeyValuePair<CaptureGroup, ILInstruction>>(); static readonly List<KeyValuePair<CaptureGroup, ILInstruction>> emptyResults = new List<KeyValuePair<CaptureGroup, ILInstruction>>();
List<KeyValuePair<CaptureGroup, ILInstruction>> results; List<KeyValuePair<CaptureGroup, ILInstruction>>? results;
/// <summary> /// <summary>
/// Gets whether the match was successful. /// Gets whether the match was successful.

3
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 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software

4
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 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
#nullable enable
using System.Linq; using System.Linq;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
@ -89,4 +91,4 @@ namespace ICSharpCode.Decompiler.IL
return false; return false;
} }
} }
} }

1
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 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
#nullable enable
namespace ICSharpCode.Decompiler.IL namespace ICSharpCode.Decompiler.IL
{ {

1
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 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
#nullable enable
namespace ICSharpCode.Decompiler.IL namespace ICSharpCode.Decompiler.IL
{ {

6
ICSharpCode.Decompiler/TypeSystem/IMember.cs

@ -62,6 +62,12 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary> /// </summary>
IType ReturnType { get; } IType ReturnType { get; }
/// <summary>
/// Gets/Sets the declaring type (incl. type arguments, if any).
/// If this is not a specialized member, the value returned is equal to <see cref="IEntity.DeclaringTypeDefinition"/>.
/// </summary>
new IType DeclaringType { get; }
/// <summary> /// <summary>
/// Gets the interface members explicitly implemented by this member. /// Gets the interface members explicitly implemented by this member.
/// </summary> /// </summary>

2
ICSharpCode.Decompiler/TypeSystem/Implementation/SyntheticRangeIndexer.cs

@ -92,7 +92,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
TypeParameterSubstitution IMember.Substitution => underlyingMethod.Substitution; TypeParameterSubstitution IMember.Substitution => underlyingMethod.Substitution;
EntityHandle IEntity.MetadataToken => underlyingMethod.MetadataToken; EntityHandle IEntity.MetadataToken => underlyingMethod.MetadataToken;
public string Name => underlyingMethod.Name; public string Name => underlyingMethod.Name;
IType IEntity.DeclaringType => underlyingMethod.DeclaringType; public IType DeclaringType => underlyingMethod.DeclaringType;
ITypeDefinition IEntity.DeclaringTypeDefinition => underlyingMethod.DeclaringTypeDefinition; ITypeDefinition IEntity.DeclaringTypeDefinition => underlyingMethod.DeclaringTypeDefinition;
IModule IEntity.ParentModule => underlyingMethod.ParentModule; IModule IEntity.ParentModule => underlyingMethod.ParentModule;
Accessibility IEntity.Accessibility => underlyingMethod.Accessibility; Accessibility IEntity.Accessibility => underlyingMethod.Accessibility;

Loading…
Cancel
Save