0
public void SomeGoodMethod(Cube cube)
{
  Friends.Show(() => cube.Solve());
}

public void SomeBadMethod(Cube cube)
{
  cube.Solve();
}

I know I can find the hundreds of methods which take a Cube parameter with reflection. How can I find the methods which do not call static method: Friends.Show (at design-time or run-time) ?

Amy B
  • 108,202
  • 21
  • 135
  • 185
  • Maybe helpful: https://stackoverflow.com/questions/2693881/can-i-use-reflection-to-inspect-the-code-in-a-method – fqhv Apr 18 '19 at 15:08
  • You can create a post build event and use Mono.Cecil to inspect IL code. Or this is not an option for you? – Aleks Andreev Apr 18 '19 at 15:10
  • 3
    If you just want to see if a call to `Friends.Show` occurs *anywhere* in a method that takes a `Cube`, whether it's ever actually invoked or not, that's doable -- statically with Roslyn and at runtime with IL inspection. On the other hand, it is possible for a method to contain a call to `Friends.Show` but never actually execute it (because it occurs in a conditional block that's never hit), and since finding out if that's always the case reduces to the halting problem (well known to be undecidable in the general case) detecting that would be, um, well, a bit harder. – Jeroen Mostert Apr 18 '19 at 15:13
  • For my purpose, "occurs anywhere" works. – Amy B Apr 18 '19 at 15:24

1 Answers1

0

Thanks to Joroen Mostert's comment, I was able to piece together some code.

foreach (var type in types)
{
  var callsShow = false;

  foreach (var method in type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
  {
    var byteArray = method.GetMethodBody()?.GetILAsByteArray();
    if (byteArray == null)
    {
      continue;
    }

    var bytes = BitConverter.ToString(byteArray);
    var isMatch = Regex.IsMatch(bytes, "14-.*-28-.*-00-2B-26");
    callsShow = callsShow || isMatch;
  }
  if (!callsShow)
  {
    MightBeBad(type);
  }
}

I produced the regex by experimentation, repeatedly calling Friends.Show in one method with various parameters and generic parameter configurations and looking for repeated sequences in the bytes. YMMV

Out of the hundreds of classes examined, 2 true positives and 10 false positives were found. The false positives were calling from inside try blocks and other unusual situations. Still, few enough to examine manually.

Also note: the pattern can differ between Debug and Release builds.

Amy B
  • 108,202
  • 21
  • 135
  • 185