Browse Source

Add support for pattern with as-cast to IDisposable.

pull/870/merge
Siegfried Pammer 8 years ago
parent
commit
d067f0cb6c
  1. 22
      ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs

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

@ -99,14 +99,26 @@ namespace ICSharpCode.Decompiler.IL.Transforms
bool MatchDisposeBlock(BlockContainer container, ILVariable objVar, bool usingNull) bool MatchDisposeBlock(BlockContainer container, ILVariable objVar, bool usingNull)
{ {
var entryPoint = container.EntryPoint; var entryPoint = container.EntryPoint;
if (entryPoint.Instructions.Count != 2 || entryPoint.IncomingEdgeCount != 1) if (entryPoint.Instructions.Count < 2 || entryPoint.Instructions.Count > 3 || entryPoint.IncomingEdgeCount != 1)
return false; return false;
if (!entryPoint.Instructions[1].MatchLeave(container, out var returnValue) || !returnValue.MatchNop()) int leaveIndex = entryPoint.Instructions.Count == 2 ? 1 : 2;
int checkIndex = entryPoint.Instructions.Count == 2 ? 0 : 1;
int castIndex = entryPoint.Instructions.Count == 3 ? 0 : -1;
bool isReference = objVar.Type.IsReferenceType != false;
if (castIndex > -1) {
if (!entryPoint.Instructions[castIndex].MatchStLoc(out var tempVar, out var isinst))
return false;
if (!isinst.MatchIsInst(out var load, out var disposableType) || !load.MatchLdLoc(objVar) || !disposableType.IsKnownType(KnownTypeCode.IDisposable))
return false;
objVar = tempVar;
isReference = true;
}
if (!entryPoint.Instructions[leaveIndex].MatchLeave(container, out var returnValue) || !returnValue.MatchNop())
return false; return false;
CallVirt callVirt; CallVirt callVirt;
// reference types have a null check. // reference types have a null check.
if (objVar.Type.IsReferenceType != false) { if (isReference) {
if (!entryPoint.Instructions[0].MatchIfInstruction(out var condition, out var disposeInst)) if (!entryPoint.Instructions[checkIndex].MatchIfInstruction(out var condition, out var disposeInst))
return false; return false;
if (!condition.MatchCompNotEquals(out var left, out var right) || !left.MatchLdLoc(objVar) || !right.MatchLdNull()) if (!condition.MatchCompNotEquals(out var left, out var right) || !left.MatchLdLoc(objVar) || !right.MatchLdNull())
return false; return false;
@ -116,7 +128,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false; return false;
callVirt = cv; callVirt = cv;
} else { } else {
if (!(entryPoint.Instructions[0] is CallVirt cv)) if (!(entryPoint.Instructions[checkIndex] is CallVirt cv))
return false; return false;
callVirt = cv; callVirt = cv;
} }

Loading…
Cancel
Save