Browse Source

Add support for using on nullables.

pull/877/head
Siegfried Pammer 8 years ago
parent
commit
2c40b45717
  1. 95
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Using.il
  2. 73
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Using.opt.il
  3. 75
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Using.opt.roslyn.il
  4. 85
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Using.roslyn.il
  5. 4
      ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs
  6. 51
      ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs

95
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Using.il

@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly dybef0h5
.assembly wgewqkaz
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
@ -20,15 +20,15 @@ @@ -20,15 +20,15 @@
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module dybef0h5.dll
// MVID: {469DF7ED-3C07-4983-A672-891B2A428600}
.module wgewqkaz.dll
// MVID: {298A3373-9EF1-4D76-BCEC-2E82A945AF55}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x003C0000
// Image base: 0x00550000
// =============== CLASS MEMBERS DECLARATION ===================
@ -302,6 +302,51 @@ @@ -302,6 +302,51 @@
IL_0034: ret
} // end of method Using::UsingStatementOnStructWithVariable
.method private hidebysig instance void
UsingStatementOnNullableStruct(valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct> us) cil managed
{
// Code size 63 (0x3f)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct> V_0,
bool V_1)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: stloc.0
.try
{
IL_0003: nop
IL_0004: ldstr "using-body: "
IL_0009: ldarg.1
IL_000a: box valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct>
IL_000f: call string [mscorlib]System.String::Concat(object,
object)
IL_0014: call void [mscorlib]System.Console::WriteLine(string)
IL_0019: nop
IL_001a: nop
IL_001b: leave.s IL_003d
} // end .try
finally
{
IL_001d: ldloca.s V_0
IL_001f: call instance bool valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct>::get_HasValue()
IL_0024: ldc.i4.0
IL_0025: ceq
IL_0027: stloc.1
IL_0028: ldloc.1
IL_0029: brtrue.s IL_003c
IL_002b: ldloc.0
IL_002c: box valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct>
IL_0031: unbox.any [mscorlib]System.IDisposable
IL_0036: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_003b: nop
IL_003c: endfinally
} // end handler
IL_003d: nop
IL_003e: ret
} // end of method Using::UsingStatementOnNullableStruct
.method public hidebysig instance void
GenericUsing<([mscorlib]System.IDisposable) T>(!!T t) cil managed
{
@ -416,6 +461,48 @@ @@ -416,6 +461,48 @@
IL_0030: ret
} // end of method Using::GenericClassUsing
.method public hidebysig instance void
GenericNullableUsing<valuetype .ctor ([mscorlib]System.ValueType, [mscorlib]System.IDisposable) T>(valuetype [mscorlib]System.Nullable`1<!!T> t) cil managed
{
// Code size 53 (0x35)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<!!T> V_0,
bool V_1)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: stloc.0
.try
{
IL_0003: nop
IL_0004: ldarg.1
IL_0005: box valuetype [mscorlib]System.Nullable`1<!!T>
IL_000a: call void [mscorlib]System.Console::WriteLine(object)
IL_000f: nop
IL_0010: nop
IL_0011: leave.s IL_0033
} // end .try
finally
{
IL_0013: ldloca.s V_0
IL_0015: call instance bool valuetype [mscorlib]System.Nullable`1<!!T>::get_HasValue()
IL_001a: ldc.i4.0
IL_001b: ceq
IL_001d: stloc.1
IL_001e: ldloc.1
IL_001f: brtrue.s IL_0032
IL_0021: ldloc.0
IL_0022: box valuetype [mscorlib]System.Nullable`1<!!T>
IL_0027: unbox.any [mscorlib]System.IDisposable
IL_002c: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0031: nop
IL_0032: endfinally
} // end handler
IL_0033: nop
IL_0034: ret
} // end of method Using::GenericNullableUsing
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

73
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Using.opt.il

@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly nwychzte
.assembly ms0npdxf
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
@ -20,15 +20,15 @@ @@ -20,15 +20,15 @@
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module nwychzte.dll
// MVID: {142BA3BD-C0CA-4005-A426-112E6C543819}
.module ms0npdxf.dll
// MVID: {060FC94F-8DAE-4720-AF67-48BEEC70FFC8}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x025B0000
// Image base: 0x030B0000
// =============== CLASS MEMBERS DECLARATION ===================
@ -241,6 +241,40 @@ @@ -241,6 +241,40 @@
IL_002d: ret
} // end of method Using::UsingStatementOnStructWithVariable
.method private hidebysig instance void
UsingStatementOnNullableStruct(valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct> us) cil managed
{
// Code size 52 (0x34)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct> V_0)
IL_0000: ldarg.1
IL_0001: stloc.0
.try
{
IL_0002: ldstr "using-body: "
IL_0007: ldarg.1
IL_0008: box valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct>
IL_000d: call string [mscorlib]System.String::Concat(object,
object)
IL_0012: call void [mscorlib]System.Console::WriteLine(string)
IL_0017: leave.s IL_0033
} // end .try
finally
{
IL_0019: ldloca.s V_0
IL_001b: call instance bool valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct>::get_HasValue()
IL_0020: brfalse.s IL_0032
IL_0022: ldloc.0
IL_0023: box valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct>
IL_0028: unbox.any [mscorlib]System.IDisposable
IL_002d: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0032: endfinally
} // end handler
IL_0033: ret
} // end of method Using::UsingStatementOnNullableStruct
.method public hidebysig instance void
GenericUsing<([mscorlib]System.IDisposable) T>(!!T t) cil managed
{
@ -327,6 +361,37 @@ @@ -327,6 +361,37 @@
IL_0025: ret
} // end of method Using::GenericClassUsing
.method public hidebysig instance void
GenericNullableUsing<valuetype .ctor ([mscorlib]System.ValueType, [mscorlib]System.IDisposable) T>(valuetype [mscorlib]System.Nullable`1<!!T> t) cil managed
{
// Code size 42 (0x2a)
.maxstack 1
.locals init (valuetype [mscorlib]System.Nullable`1<!!T> V_0)
IL_0000: ldarg.1
IL_0001: stloc.0
.try
{
IL_0002: ldarg.1
IL_0003: box valuetype [mscorlib]System.Nullable`1<!!T>
IL_0008: call void [mscorlib]System.Console::WriteLine(object)
IL_000d: leave.s IL_0029
} // end .try
finally
{
IL_000f: ldloca.s V_0
IL_0011: call instance bool valuetype [mscorlib]System.Nullable`1<!!T>::get_HasValue()
IL_0016: brfalse.s IL_0028
IL_0018: ldloc.0
IL_0019: box valuetype [mscorlib]System.Nullable`1<!!T>
IL_001e: unbox.any [mscorlib]System.IDisposable
IL_0023: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0028: endfinally
} // end handler
IL_0029: ret
} // end of method Using::GenericNullableUsing
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

75
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Using.opt.roslyn.il

@ -25,14 +25,14 @@ @@ -25,14 +25,14 @@
.ver 0:0:0:0
}
.module Using.dll
// MVID: {F795B575-6F0C-4E56-817C-B7689ECEE4A6}
// MVID: {AD3F5551-3D76-468D-A005-EEF5916A56A8}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x003F0000
// Image base: 0x015E0000
// =============== CLASS MEMBERS DECLARATION ===================
@ -218,6 +218,43 @@ @@ -218,6 +218,43 @@
IL_002d: ret
} // end of method Using::UsingStatementOnStructWithVariable
.method private hidebysig instance void
UsingStatementOnNullableStruct(valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct> us) cil managed
{
// Code size 57 (0x39)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct> V_0,
valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct V_1)
IL_0000: ldarg.1
IL_0001: stloc.0
.try
{
IL_0002: ldstr "using-body: "
IL_0007: ldarg.1
IL_0008: box valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct>
IL_000d: call string [mscorlib]System.String::Concat(object,
object)
IL_0012: call void [mscorlib]System.Console::WriteLine(string)
IL_0017: leave.s IL_0038
} // end .try
finally
{
IL_0019: ldloca.s V_0
IL_001b: call instance bool valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct>::get_HasValue()
IL_0020: brfalse.s IL_0037
IL_0022: ldloca.s V_0
IL_0024: call instance !0 valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct>::GetValueOrDefault()
IL_0029: stloc.1
IL_002a: ldloca.s V_1
IL_002c: constrained. ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct
IL_0032: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0037: endfinally
} // end handler
IL_0038: ret
} // end of method Using::UsingStatementOnNullableStruct
.method public hidebysig instance void
GenericUsing<([mscorlib]System.IDisposable) T>(!!T t) cil managed
{
@ -304,6 +341,40 @@ @@ -304,6 +341,40 @@
IL_0023: ret
} // end of method Using::GenericClassUsing
.method public hidebysig instance void
GenericNullableUsing<valuetype .ctor ([mscorlib]System.IDisposable, [mscorlib]System.ValueType) T>(valuetype [mscorlib]System.Nullable`1<!!T> t) cil managed
{
// Code size 47 (0x2f)
.maxstack 1
.locals init (valuetype [mscorlib]System.Nullable`1<!!T> V_0,
!!T V_1)
IL_0000: ldarg.1
IL_0001: stloc.0
.try
{
IL_0002: ldarg.1
IL_0003: box valuetype [mscorlib]System.Nullable`1<!!T>
IL_0008: call void [mscorlib]System.Console::WriteLine(object)
IL_000d: leave.s IL_002e
} // end .try
finally
{
IL_000f: ldloca.s V_0
IL_0011: call instance bool valuetype [mscorlib]System.Nullable`1<!!T>::get_HasValue()
IL_0016: brfalse.s IL_002d
IL_0018: ldloca.s V_0
IL_001a: call instance !0 valuetype [mscorlib]System.Nullable`1<!!T>::GetValueOrDefault()
IL_001f: stloc.1
IL_0020: ldloca.s V_1
IL_0022: constrained. !!T
IL_0028: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_002d: endfinally
} // end handler
IL_002e: ret
} // end of method Using::GenericNullableUsing
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

85
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Using.roslyn.il

@ -25,14 +25,14 @@ @@ -25,14 +25,14 @@
.ver 0:0:0:0
}
.module Using.dll
// MVID: {297FC1D9-B0EF-4868-95FD-EA7385BE32F8}
// MVID: {7437788B-6603-4074-AE80-83AE987F007D}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x027F0000
// Image base: 0x011B0000
// =============== CLASS MEMBERS DECLARATION ===================
@ -247,6 +247,48 @@ @@ -247,6 +247,48 @@
IL_0032: ret
} // end of method Using::UsingStatementOnStructWithVariable
.method private hidebysig instance void
UsingStatementOnNullableStruct(valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct> us) cil managed
{
// Code size 62 (0x3e)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct> V_0,
valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct V_1)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: stloc.0
.try
{
IL_0003: nop
IL_0004: ldstr "using-body: "
IL_0009: ldarg.1
IL_000a: box valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct>
IL_000f: call string [mscorlib]System.String::Concat(object,
object)
IL_0014: call void [mscorlib]System.Console::WriteLine(string)
IL_0019: nop
IL_001a: nop
IL_001b: leave.s IL_003d
} // end .try
finally
{
IL_001d: ldloca.s V_0
IL_001f: call instance bool valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct>::get_HasValue()
IL_0024: brfalse.s IL_003c
IL_0026: ldloca.s V_0
IL_0028: call instance !0 valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct>::GetValueOrDefault()
IL_002d: stloc.1
IL_002e: ldloca.s V_1
IL_0030: constrained. ICSharpCode.Decompiler.Tests.TestCases.Pretty.Using/UsingStruct
IL_0036: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_003b: nop
IL_003c: endfinally
} // end handler
IL_003d: ret
} // end of method Using::UsingStatementOnNullableStruct
.method public hidebysig instance void
GenericUsing<([mscorlib]System.IDisposable) T>(!!T t) cil managed
{
@ -348,6 +390,45 @@ @@ -348,6 +390,45 @@
IL_0028: ret
} // end of method Using::GenericClassUsing
.method public hidebysig instance void
GenericNullableUsing<valuetype .ctor ([mscorlib]System.IDisposable, [mscorlib]System.ValueType) T>(valuetype [mscorlib]System.Nullable`1<!!T> t) cil managed
{
// Code size 52 (0x34)
.maxstack 1
.locals init (valuetype [mscorlib]System.Nullable`1<!!T> V_0,
!!T V_1)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: stloc.0
.try
{
IL_0003: nop
IL_0004: ldarg.1
IL_0005: box valuetype [mscorlib]System.Nullable`1<!!T>
IL_000a: call void [mscorlib]System.Console::WriteLine(object)
IL_000f: nop
IL_0010: nop
IL_0011: leave.s IL_0033
} // end .try
finally
{
IL_0013: ldloca.s V_0
IL_0015: call instance bool valuetype [mscorlib]System.Nullable`1<!!T>::get_HasValue()
IL_001a: brfalse.s IL_0032
IL_001c: ldloca.s V_0
IL_001e: call instance !0 valuetype [mscorlib]System.Nullable`1<!!T>::GetValueOrDefault()
IL_0023: stloc.1
IL_0024: ldloca.s V_1
IL_0026: constrained. !!T
IL_002c: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0031: nop
IL_0032: endfinally
} // end handler
IL_0033: ret
} // end of method Using::GenericNullableUsing
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

4
ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs

@ -543,7 +543,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -543,7 +543,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// <summary>
/// Matches 'call get_HasValue(ldloca v)'
/// </summary>
static bool MatchHasValueCall(ILInstruction inst, out ILVariable v)
internal static bool MatchHasValueCall(ILInstruction inst, out ILVariable v)
{
v = null;
if (!(inst is Call call))
@ -560,7 +560,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -560,7 +560,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// <summary>
/// Matches 'call get_HasValue(ldloca v)'
/// </summary>
static bool MatchHasValueCall(ILInstruction inst, ILVariable v)
internal static bool MatchHasValueCall(ILInstruction inst, ILVariable v)
{
return MatchHasValueCall(inst, out var v2) && v == v2;
}

51
ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs

@ -74,7 +74,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -74,7 +74,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (i < 1) return false;
if (!(block.Instructions[i] is TryFinally tryFinally) || !(block.Instructions[i - 1] is StLoc storeInst))
return false;
if (!storeInst.Variable.Type.GetAllBaseTypes().Any(b => b.IsKnownType(KnownTypeCode.IDisposable)))
if (!(storeInst.Value.MatchLdNull() || NullableType.GetUnderlyingType(storeInst.Variable.Type).GetAllBaseTypes().Any(b => b.IsKnownType(KnownTypeCode.IDisposable))))
return false;
if (storeInst.Variable.LoadInstructions.Any(ld => !ld.IsDescendantOf(tryFinally)))
return false;
@ -112,29 +112,54 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -112,29 +112,54 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!entryPoint.Instructions[leaveIndex].MatchLeave(container, out var returnValue) || !returnValue.MatchNop())
return false;
CallVirt callVirt;
// reference types have a null check.
if (isReference) {
if (objVar.Type.IsKnownType(KnownTypeCode.NullableOfT)) {
if (!entryPoint.Instructions[checkIndex].MatchIfInstruction(out var condition, out var disposeInst))
return false;
if (!condition.MatchCompNotEquals(out var left, out var right) || !left.MatchLdLoc(objVar) || !right.MatchLdNull())
if (!(NullableLiftingTransform.MatchHasValueCall(condition, out var v) && v == objVar))
return false;
if (!(disposeInst is Block disposeBlock) || disposeBlock.Instructions.Count != 1)
return false;
if (!(disposeBlock.Instructions[0] is CallVirt cv))
return false;
callVirt = cv;
if (callVirt.Method.FullName != "System.IDisposable.Dispose")
return false;
if (callVirt.Method.Parameters.Count > 0)
return false;
if (callVirt.Arguments.Count != 1)
return false;
var firstArg = cv.Arguments.FirstOrDefault();
if (!(firstArg.MatchUnboxAny(out var innerArg1, out var unboxType) && unboxType.IsKnownType(KnownTypeCode.IDisposable)))
return false;
if (!(innerArg1.MatchBox(out firstArg, out var boxType) && boxType.IsKnownType(KnownTypeCode.NullableOfT) &&
NullableType.GetUnderlyingType(boxType).Equals(NullableType.GetUnderlyingType(objVar.Type))))
return false;
return firstArg.MatchLdLoc(objVar);
} else {
if (!(entryPoint.Instructions[checkIndex] is CallVirt cv))
if (isReference) {
// reference types have a null check.
if (!entryPoint.Instructions[checkIndex].MatchIfInstruction(out var condition, out var disposeInst))
return false;
if (!condition.MatchCompNotEquals(out var left, out var right) || !left.MatchLdLoc(objVar) || !right.MatchLdNull())
return false;
if (!(disposeInst is Block disposeBlock) || disposeBlock.Instructions.Count != 1)
return false;
if (!(disposeBlock.Instructions[0] is CallVirt cv))
return false;
callVirt = cv;
} else {
if (!(entryPoint.Instructions[checkIndex] is CallVirt cv))
return false;
callVirt = cv;
}
if (callVirt.Method.FullName != "System.IDisposable.Dispose")
return false;
callVirt = cv;
if (callVirt.Method.Parameters.Count > 0)
return false;
if (callVirt.Arguments.Count != 1)
return false;
return callVirt.Arguments[0].MatchLdLocRef(objVar) || (usingNull && callVirt.Arguments[0].MatchLdNull());
}
if (callVirt.Method.FullName != "System.IDisposable.Dispose")
return false;
if (callVirt.Method.Parameters.Count > 0)
return false;
if (callVirt.Arguments.Count != 1)
return false;
return callVirt.Arguments[0].MatchLdLocRef(objVar) || (usingNull && callVirt.Arguments[0].MatchLdNull());
}
}
}

Loading…
Cancel
Save