Browse Source

Merge pull request #2841 from ElektroKill/fix/foreach-issue-2199

pull/2754/head
Siegfried Pammer 3 years ago committed by GitHub
parent
commit
3d117a5bea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
  2. 20
      ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBNonGenericForEach.cs
  3. 11
      ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBNonGenericForEach.vb
  4. 6
      ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs
  5. 14
      ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs

2
ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj

@ -114,6 +114,8 @@ @@ -114,6 +114,8 @@
<Compile Include="TestAssemblyResolver.cs" />
<None Include="TestCases\VBPretty\VBAutomaticEvents.vb" />
<Compile Include="TestCases\VBPretty\VBAutomaticEvents.cs" />
<Compile Include="TestCases\VBPretty\VBNonGenericForEach.cs" />
<None Include="TestCases\VBPretty\VBNonGenericForEach.vb" />
<Compile Include="TypeSystem\ReflectionHelperTests.cs" />
<None Include="TestCases\Pretty\MetadataAttributes.cs" />
<None Include="TestCases\Correctness\ComInterop.cs" />

20
ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBNonGenericForEach.cs

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
using System;
using System.Collections;
using System.Runtime.CompilerServices;
public class VBNonGenericForEach
{
public static void M()
{
ArrayList arrayList = new ArrayList();
foreach (object item in arrayList)
{
#if ROSLYN && OPT
Console.WriteLine(RuntimeHelpers.GetObjectValue(RuntimeHelpers.GetObjectValue(item)));
#else
object objectValue = RuntimeHelpers.GetObjectValue(item);
Console.WriteLine(RuntimeHelpers.GetObjectValue(objectValue));
#endif
}
}
}

11
ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBNonGenericForEach.vb

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
Imports System
Imports System.Collections
Public Class VBNonGenericForEach
Public Shared Sub M()
Dim collection = New ArrayList
For Each element In collection
Console.WriteLine(element)
Next
End Sub
End Class

6
ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs

@ -131,6 +131,12 @@ namespace ICSharpCode.Decompiler.Tests @@ -131,6 +131,12 @@ namespace ICSharpCode.Decompiler.Tests
await Run(options: options | CompilerOptions.Library);
}
[Test]
public async Task VBNonGenericForEach([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
await Run(options: options | CompilerOptions.Library);
}
async Task Run([CallerMemberName] string testName = null, CompilerOptions options = CompilerOptions.UseDebug, DecompilerSettings settings = null)
{
var vbFile = Path.Combine(TestCasePath, testName + ".vb");

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

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// Copyright (c) 2017 Siegfried Pammer
// 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
@ -316,7 +316,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -316,7 +316,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// reference types have a null check.
if (!checkInst.MatchIfInstruction(out var condition, out var disposeInst))
return false;
if (!MatchNullCheckOrTypeCheck(condition, ref objVar, disposeTypeCode))
if (!MatchNullCheckOrTypeCheck(condition, ref objVar, disposeTypeCode, out var isInlinedIsInst))
return false;
if (!(disposeInst is Block disposeBlock) || disposeBlock.Instructions.Count != 1)
return false;
@ -333,6 +333,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -333,6 +333,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false;
if (target.MatchBox(out var newTarget, out var type) && type.Equals(objVar.Type))
target = newTarget;
else if (isInlinedIsInst && target.MatchIsInst(out newTarget, out type) && type.IsKnownType(disposeTypeCode))
target = newTarget;
disposeCall = cv;
}
else if (objVar.Type.Kind == TypeKind.Struct && objVar.Type.IsByRefLike)
@ -381,10 +383,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -381,10 +383,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
}
bool MatchNullCheckOrTypeCheck(ILInstruction condition, ref ILVariable objVar, KnownTypeCode disposeType)
bool MatchNullCheckOrTypeCheck(ILInstruction condition, ref ILVariable objVar, KnownTypeCode disposeType, out bool isInlinedIsInst)
{
isInlinedIsInst = false;
if (condition.MatchCompNotEquals(out var left, out var right))
{
if (left.MatchIsInst(out var arg, out var type) && type.IsKnownType(disposeType))
{
isInlinedIsInst = true;
left = arg;
}
if (!left.MatchLdLoc(objVar) || !right.MatchLdNull())
return false;
return true;

Loading…
Cancel
Save