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

7
ICSharpCode.Decompiler/IL/ILAstWritingOptions.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2017 Daniel Grunwald
#nullable enable
// Copyright (c) 2017 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -84,7 +85,7 @@ namespace ICSharpCode.Decompiler.IL @@ -84,7 +85,7 @@ namespace ICSharpCode.Decompiler.IL
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
@ -94,6 +95,6 @@ namespace ICSharpCode.Decompiler.IL @@ -94,6 +95,6 @@ namespace ICSharpCode.Decompiler.IL
PropertyChanged?.Invoke(this, e);
}
public event PropertyChangedEventHandler PropertyChanged;
public event PropertyChangedEventHandler? PropertyChanged;
}
}

5
ICSharpCode.Decompiler/IL/ILInstructionExtensions.cs

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

7
ICSharpCode.Decompiler/IL/ILTypeExtensions.cs

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

20
ICSharpCode.Decompiler/IL/ILVariable.cs

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

3
ICSharpCode.Decompiler/IL/InstructionFlags.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2014 Daniel Grunwald
#nullable enable
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software

3
ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2014 Daniel Grunwald
#nullable enable
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software

7
ICSharpCode.Decompiler/IL/Instructions/Await.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2017 Daniel Grunwald
#nullable enable
// Copyright (c) 2017 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -22,7 +23,7 @@ namespace ICSharpCode.Decompiler.IL @@ -22,7 +23,7 @@ namespace ICSharpCode.Decompiler.IL
{
partial class Await
{
public IMethod GetAwaiterMethod;
public IMethod GetResultMethod;
public IMethod? GetAwaiterMethod;
public IMethod? GetResultMethod;
}
}

5
ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2014 Daniel Grunwald
#nullable enable
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -214,5 +215,3 @@ namespace ICSharpCode.Decompiler.IL @@ -214,5 +215,3 @@ namespace ICSharpCode.Decompiler.IL
}
}
}

41
ICSharpCode.Decompiler/IL/Instructions/Block.cs

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

32
ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2014 Daniel Grunwald
#nullable enable
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -19,11 +20,11 @@ @@ -19,11 +20,11 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.IL
{
/// <summary>
@ -57,13 +58,18 @@ namespace ICSharpCode.Decompiler.IL @@ -57,13 +58,18 @@ namespace ICSharpCode.Decompiler.IL
}
}
Block entryPoint;
Block? entryPoint;
/// <summary>
/// Gets the container's entry point. This is the first block in the Blocks collection.
/// </summary>
public Block EntryPoint {
get { return entryPoint; }
get {
// HACK: While it's possible to have BlockContainers without entry point,
// normally every container must have an entry point according to its invariant.
// Thus it's easier on the transforms if this property returns a non-nullable EntryPoint.
return entryPoint!;
}
private set {
if (entryPoint != null && IsConnected)
entryPoint.IncomingEdgeCount--;
@ -102,7 +108,7 @@ namespace ICSharpCode.Decompiler.IL @@ -102,7 +108,7 @@ namespace ICSharpCode.Decompiler.IL
protected internal override void InstructionCollectionUpdateComplete()
{
base.InstructionCollectionUpdateComplete();
this.EntryPoint = this.Blocks.FirstOrDefault();
this.EntryPoint = this.Blocks.FirstOrDefault()!;
}
protected override void Connected()
@ -174,7 +180,7 @@ namespace ICSharpCode.Decompiler.IL @@ -174,7 +180,7 @@ namespace ICSharpCode.Decompiler.IL
return Blocks[index];
}
protected override void SetChild(int index, ILInstruction value)
protected override void SetChild(int index, ILInstruction? value)
{
if (Blocks[index] != value)
throw new InvalidOperationException("Cannot replace blocks in BlockContainer");
@ -189,12 +195,12 @@ namespace ICSharpCode.Decompiler.IL @@ -189,12 +195,12 @@ namespace ICSharpCode.Decompiler.IL
{
base.CheckInvariant(phase);
Debug.Assert(Blocks.Count > 0 && EntryPoint == Blocks[0]);
Debug.Assert(!IsConnected || EntryPoint?.IncomingEdgeCount >= 1);
Debug.Assert(EntryPoint == null || Parent is ILFunction || !ILRangeIsEmpty);
Debug.Assert(!IsConnected || EntryPoint.IncomingEdgeCount >= 1);
Debug.Assert(Parent is ILFunction || !ILRangeIsEmpty);
Debug.Assert(Blocks.All(b => b.HasFlag(InstructionFlags.EndPointUnreachable)));
Debug.Assert(Blocks.All(b => b.Kind == BlockKind.ControlFlow)); // this also implies that the blocks don't use FinalInstruction
Debug.Assert(TopologicalSort(deleteUnreachableBlocks: true).Count == Blocks.Count, "Container should not have any unreachable blocks");
Block bodyStartBlock;
Block? bodyStartBlock;
switch (Kind)
{
case ContainerKind.Normal:
@ -319,7 +325,7 @@ namespace ICSharpCode.Decompiler.IL @@ -319,7 +325,7 @@ namespace ICSharpCode.Decompiler.IL
Blocks.ReplaceList(newOrder);
}
public static BlockContainer FindClosestContainer(ILInstruction inst)
public static BlockContainer? FindClosestContainer(ILInstruction? inst)
{
while (inst != null)
{
@ -330,18 +336,18 @@ namespace ICSharpCode.Decompiler.IL @@ -330,18 +336,18 @@ namespace ICSharpCode.Decompiler.IL
return null;
}
public static BlockContainer FindClosestSwitchContainer(ILInstruction inst)
public static BlockContainer? FindClosestSwitchContainer(ILInstruction? inst)
{
while (inst != null)
{
if (inst is BlockContainer bc && bc.entryPoint.Instructions.FirstOrDefault() is SwitchInstruction)
if (inst is BlockContainer { Kind: ContainerKind.Switch } bc)
return bc;
inst = inst.Parent;
}
return null;
}
public bool MatchConditionBlock(Block block, out ILInstruction condition, out Block bodyStartBlock)
public bool MatchConditionBlock(Block block, [NotNullWhen(true)] out ILInstruction? condition, [NotNullWhen(true)] out Block? bodyStartBlock)
{
condition = null;
bodyStartBlock = null;

25
ICSharpCode.Decompiler/IL/Instructions/Branch.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2014 Daniel Grunwald
#nullable enable
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -30,7 +31,7 @@ namespace ICSharpCode.Decompiler.IL @@ -30,7 +31,7 @@ namespace ICSharpCode.Decompiler.IL
partial class Branch : SimpleInstruction, IBranchOrLeaveInstruction
{
readonly int targetILOffset;
Block targetBlock;
Block? targetBlock;
public Branch(int targetILOffset) : base(OpCode.Branch)
{
@ -48,7 +49,11 @@ namespace ICSharpCode.Decompiler.IL @@ -48,7 +49,11 @@ namespace ICSharpCode.Decompiler.IL
}
public Block TargetBlock {
get { return targetBlock; }
get {
// HACK: We treat TargetBlock as non-nullable publicly, because it's only null inside
// the ILReader, and becomes non-null once the BlockBuilder has run.
return targetBlock!;
}
set {
if (targetBlock != null && IsConnected)
targetBlock.IncomingEdgeCount--;
@ -62,7 +67,7 @@ namespace ICSharpCode.Decompiler.IL @@ -62,7 +67,7 @@ namespace ICSharpCode.Decompiler.IL
/// Gets the BlockContainer that contains the target block.
/// </summary>
public BlockContainer TargetContainer {
get { return (BlockContainer)targetBlock?.Parent; }
get { return (BlockContainer)targetBlock?.Parent!; }
}
protected override void Connected()
@ -92,9 +97,9 @@ namespace ICSharpCode.Decompiler.IL @@ -92,9 +97,9 @@ namespace ICSharpCode.Decompiler.IL
}
}
internal static bool GetExecutesFinallyBlock(ILInstruction inst, BlockContainer container)
internal static bool GetExecutesFinallyBlock(ILInstruction? inst, BlockContainer? container)
{
for (; inst != container; inst = inst.Parent)
for (; inst != container && inst != null; inst = inst.Parent)
{
if (inst.Parent is TryFinally && inst.SlotInfo == TryFinally.TryBlockSlot)
return true;
@ -107,9 +112,9 @@ namespace ICSharpCode.Decompiler.IL @@ -107,9 +112,9 @@ namespace ICSharpCode.Decompiler.IL
base.CheckInvariant(phase);
if (phase > ILPhase.InILReader)
{
Debug.Assert(targetBlock.Parent is BlockContainer);
Debug.Assert(this.IsDescendantOf(targetBlock.Parent));
Debug.Assert(targetBlock.Parent.Children[targetBlock.ChildIndex] == targetBlock);
Debug.Assert(targetBlock?.Parent is BlockContainer);
Debug.Assert(this.IsDescendantOf(targetBlock!.Parent!));
Debug.Assert(targetBlock!.Parent!.Children[targetBlock.ChildIndex] == targetBlock);
}
}
@ -118,7 +123,7 @@ namespace ICSharpCode.Decompiler.IL @@ -118,7 +123,7 @@ namespace ICSharpCode.Decompiler.IL
WriteILRange(output, options);
output.Write(OpCode);
output.Write(' ');
output.WriteLocalReference(TargetLabel, (object)targetBlock ?? TargetILOffset);
output.WriteLocalReference(TargetLabel, (object?)targetBlock ?? TargetILOffset);
}
}

5
ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs

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

15
ICSharpCode.Decompiler/IL/Instructions/CallInstruction.cs

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

6
ICSharpCode.Decompiler/IL/Instructions/Comp.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2014 Daniel Grunwald
#nullable enable
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -21,7 +22,6 @@ using System.Diagnostics; @@ -21,7 +22,6 @@ using System.Diagnostics;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.IL
{
@ -231,5 +231,3 @@ namespace ICSharpCode.Decompiler.IL @@ -231,5 +231,3 @@ namespace ICSharpCode.Decompiler.IL
}
}
}

5
ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs

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

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

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2014 Daniel Grunwald
#nullable enable
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software

9
ICSharpCode.Decompiler/IL/Instructions/DeconstructResultInstruction.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2020 Siegfried Pammer
#nullable enable
// Copyright (c) 2020 Siegfried Pammer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -47,9 +48,9 @@ namespace ICSharpCode.Decompiler.IL @@ -47,9 +48,9 @@ namespace ICSharpCode.Decompiler.IL
output.Write(')');
}
MatchInstruction FindMatch()
MatchInstruction? FindMatch()
{
for (ILInstruction inst = this; inst != null; inst = inst.Parent)
for (ILInstruction? inst = this; inst != null; inst = inst.Parent)
{
if (inst.Parent is MatchInstruction match && inst != match.TestedOperand)
return match;
@ -61,7 +62,7 @@ namespace ICSharpCode.Decompiler.IL @@ -61,7 +62,7 @@ namespace ICSharpCode.Decompiler.IL
{
var matchInst = FindMatch();
Debug.Assert(matchInst != null && (matchInst.IsDeconstructCall || matchInst.IsDeconstructTuple));
Debug.Assert(Argument.MatchLdLoc(matchInst.Variable));
Debug.Assert(Argument.MatchLdLoc(matchInst!.Variable));
var outParamType = matchInst.GetDeconstructResultType(this.Index);
Debug.Assert(outParamType.GetStackType() == ResultType);
}

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

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2017 Siegfried Pammer
#nullable enable
// Copyright (c) 2017 Siegfried Pammer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software

41
ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs

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

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

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

30
ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs

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

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

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

5
ICSharpCode.Decompiler/IL/Instructions/ILVariableCollection.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2016 Daniel Grunwald
#nullable enable
// Copyright (c) 2016 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -128,7 +129,7 @@ namespace ICSharpCode.Decompiler.IL @@ -128,7 +129,7 @@ namespace ICSharpCode.Decompiler.IL
{
// However, remove unused this-parameters of delegates, expression trees, etc.
// These will be replaced with the top-level function's this-parameter.
if (v.Index == -1 && v.Function.Kind != ILFunctionKind.TopLevelFunction)
if (v.Index == -1 && v.Function!.Kind != ILFunctionKind.TopLevelFunction)
return true;
return false;
}

9
ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2014 Daniel Grunwald
#nullable enable
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -35,7 +36,7 @@ namespace ICSharpCode.Decompiler.IL @@ -35,7 +36,7 @@ namespace ICSharpCode.Decompiler.IL
/// </remarks>
partial class IfInstruction : ILInstruction
{
public IfInstruction(ILInstruction condition, ILInstruction trueInst, ILInstruction falseInst = null) : base(OpCode.IfInstruction)
public IfInstruction(ILInstruction condition, ILInstruction trueInst, ILInstruction? falseInst = null) : base(OpCode.IfInstruction)
{
this.Condition = condition;
this.TrueInst = trueInst;
@ -47,7 +48,7 @@ namespace ICSharpCode.Decompiler.IL @@ -47,7 +48,7 @@ namespace ICSharpCode.Decompiler.IL
return new IfInstruction(lhs, rhs, new LdcI4(0));
}
public static IfInstruction LogicOr(ILInstruction lhs, ILInstruction rhs)
public static IfInstruction LogicOr(ILInstruction lhs, ILInstruction? rhs)
{
return new IfInstruction(lhs, new LdcI4(1), rhs);
}
@ -126,7 +127,7 @@ namespace ICSharpCode.Decompiler.IL @@ -126,7 +127,7 @@ namespace ICSharpCode.Decompiler.IL
if (slot == IfInstruction.ConditionSlot)
return true;
if (slot == IfInstruction.TrueInstSlot || slot == IfInstruction.FalseInstSlot || slot == NullCoalescingInstruction.FallbackInstSlot)
return IsInConditionSlot(inst.Parent);
return IsInConditionSlot(inst.Parent!);
if (inst.Parent is Comp comp)
{
if (comp.Left == inst && comp.Right.MatchLdcI4(0))

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

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2014 Daniel Grunwald
#nullable enable
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software

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

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2014 Daniel Grunwald
#nullable enable
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software

13
ICSharpCode.Decompiler/IL/Instructions/Leave.cs

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

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

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2017 Siegfried Pammer
#nullable enable
// Copyright (c) 2017 Siegfried Pammer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software

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

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2017 Daniel Grunwald
#nullable enable
// Copyright (c) 2017 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software

14
ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs

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

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

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2014 Daniel Grunwald
#nullable enable
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software

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

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2017 Siegfried Pammer
#nullable enable
// Copyright (c) 2017 Siegfried Pammer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software

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

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2018 Daniel Grunwald
#nullable enable
// Copyright (c) 2018 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software

75
ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs

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

13
ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2014 Daniel Grunwald
#nullable enable
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -40,7 +41,7 @@ namespace ICSharpCode.Decompiler.IL @@ -40,7 +41,7 @@ namespace ICSharpCode.Decompiler.IL
partial class Nop
{
public string Comment;
public string? Comment;
public NopKind Kind;
@ -61,10 +62,10 @@ namespace ICSharpCode.Decompiler.IL @@ -61,10 +62,10 @@ namespace ICSharpCode.Decompiler.IL
partial class InvalidBranch : SimpleInstruction
{
public string Message;
public string? Message;
public StackType ExpectedResultType = StackType.Void;
public InvalidBranch(string message) : this()
public InvalidBranch(string? message) : this()
{
this.Message = message;
}
@ -88,10 +89,10 @@ namespace ICSharpCode.Decompiler.IL @@ -88,10 +89,10 @@ namespace ICSharpCode.Decompiler.IL
partial class InvalidExpression : SimpleInstruction
{
public string Message;
public string? Message;
public StackType ExpectedResultType = StackType.Unknown;
public InvalidExpression(string message) : this()
public InvalidExpression(string? message) : this()
{
this.Message = message;
}

7
ICSharpCode.Decompiler/IL/Instructions/StLoc.cs

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

13
ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2017 Siegfried Pammer
#nullable enable
// Copyright (c) 2017 Siegfried Pammer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -23,23 +24,23 @@ namespace ICSharpCode.Decompiler.IL @@ -23,23 +24,23 @@ namespace ICSharpCode.Decompiler.IL
{
partial class StringToInt
{
public List<(string Key, int Value)> Map { get; }
public List<(string? Key, int Value)> Map { get; }
public StringToInt(ILInstruction argument, List<(string Key, int Value)> map)
public StringToInt(ILInstruction? argument, List<(string? Key, int Value)> map)
: base(OpCode.StringToInt)
{
this.Argument = argument;
this.Map = map;
}
public StringToInt(ILInstruction argument, string[] map)
public StringToInt(ILInstruction? argument, string?[] map)
: this(argument, ArrayToDictionary(map))
{
}
static List<(string Key, int Value)> ArrayToDictionary(string[] map)
static List<(string? Key, int Value)> ArrayToDictionary(string?[] map)
{
var dict = new List<(string Key, int Value)>();
var dict = new List<(string? Key, int Value)>();
for (int i = 0; i < map.Length; i++)
{
dict.Add((map[i], i));

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

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

11
ICSharpCode.Decompiler/IL/Instructions/TryInstruction.cs

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

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

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2014 Daniel Grunwald
#nullable enable
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software

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

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2017 Siegfried Pammer
#nullable enable
// Copyright (c) 2017 Siegfried Pammer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software

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

@ -1,8 +1,5 @@ @@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
#nullable enable
using System;
namespace ICSharpCode.Decompiler.IL.Patterns
{
@ -37,19 +34,20 @@ namespace ICSharpCode.Decompiler.IL.Patterns @@ -37,19 +34,20 @@ namespace ICSharpCode.Decompiler.IL.Patterns
partial class AnyNode : PatternInstruction
{
CaptureGroup group;
CaptureGroup? group;
public AnyNode(CaptureGroup group = null)
public AnyNode(CaptureGroup? group = null)
: base(OpCode.AnyNode)
{
this.group = group;
}
protected internal override bool PerformMatch(ILInstruction other, ref Match match)
protected internal override bool PerformMatch(ILInstruction? other, ref Match match)
{
if (other == null)
return false;
match.Add(group, other);
if (group != null)
match.Add(group, other);
return true;
}
}

13
ICSharpCode.Decompiler/IL/Patterns/ListMatch.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2016 Daniel Grunwald
#nullable enable
// Copyright (c) 2016 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -44,7 +45,7 @@ namespace ICSharpCode.Decompiler.IL.Patterns @@ -44,7 +45,7 @@ namespace ICSharpCode.Decompiler.IL.Patterns
/// If the method returns true, it adds the capture groups (if any) to the match.
/// If the method returns false, the match object remains in a partially-updated state and needs to be restored
/// before it can be reused.</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);
do
@ -107,14 +108,14 @@ namespace ICSharpCode.Decompiler.IL.Patterns @@ -107,14 +108,14 @@ namespace ICSharpCode.Decompiler.IL.Patterns
/// <summary>
/// The syntax list we are matching against.
/// </summary>
internal readonly IReadOnlyList<ILInstruction> SyntaxList;
internal readonly IReadOnlyList<ILInstruction?> SyntaxList;
/// <summary>
/// The current index in the syntax list.
/// </summary>
internal int SyntaxIndex;
ListMatch(IReadOnlyList<ILInstruction> syntaxList)
ListMatch(IReadOnlyList<ILInstruction?> syntaxList)
{
this.SyntaxList = syntaxList;
this.SyntaxIndex = 0;
@ -122,8 +123,8 @@ namespace ICSharpCode.Decompiler.IL.Patterns @@ -122,8 +123,8 @@ namespace ICSharpCode.Decompiler.IL.Patterns
this.restoreStack = null;
}
List<SavePoint> backtrackingStack;
Stack<int> restoreStack;
List<SavePoint>? backtrackingStack;
Stack<int>? restoreStack;
void AddSavePoint(SavePoint savepoint)
{

5
ICSharpCode.Decompiler/IL/Patterns/Match.cs

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

3
ICSharpCode.Decompiler/IL/PrimitiveType.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
// Copyright (c) 2014 Daniel Grunwald
#nullable enable
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software

4
ICSharpCode.Decompiler/IL/SemanticHelper.cs

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#nullable enable
using System.Linq;
using ICSharpCode.Decompiler.Util;
@ -89,4 +91,4 @@ namespace ICSharpCode.Decompiler.IL @@ -89,4 +91,4 @@ namespace ICSharpCode.Decompiler.IL
return false;
}
}
}
}

1
ICSharpCode.Decompiler/IL/SlotInfo.cs

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#nullable enable
namespace ICSharpCode.Decompiler.IL
{

1
ICSharpCode.Decompiler/IL/StackType.cs

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#nullable enable
namespace ICSharpCode.Decompiler.IL
{

6
ICSharpCode.Decompiler/TypeSystem/IMember.cs

@ -62,6 +62,12 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -62,6 +62,12 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
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>
/// Gets the interface members explicitly implemented by this member.
/// </summary>

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

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

Loading…
Cancel
Save