Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save SimonCropp/0fa9806e8284a89a2866b43e5cbe9d36 to your computer and use it in GitHub Desktop.
Save SimonCropp/0fa9806e8284a89a2866b43e5cbe9d36 to your computer and use it in GitHub Desktop.
missing task return test
using System;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;
public static class MissingTaskUsage
{
public static void CheckForMissingTaskUsage(string assemblyPath)
{
var readerParameters = new ReaderParameters
{
ReadSymbols = true
};
var moduleDefinition = ModuleDefinition.ReadModule(assemblyPath,readerParameters);
foreach (var type in moduleDefinition.GetTypes())
{
foreach (var method in type.Methods)
{
if (!method.HasBody)
{
continue;
}
CheckForMissingTaskUsage(method);
}
}
}
static void CheckForMissingTaskUsage(MethodDefinition method)
{
MethodReference taskMethod = null;
foreach (var instruction in method.Body.Instructions)
{
if (taskMethod != null)
{
if (instruction.OpCode == OpCodes.Pop)
{
var declaringType = method.GetDeclaringType();
var lineNumber = instruction.Previous.GetPreviousLineNumber();
throw new Exception($"Type {declaringType.FullName} contains a call to `{taskMethod.DeclaringType.Name}.{taskMethod.Name}` near line {lineNumber} where not usage of the returned Task is detected.");
}
}
var operand = instruction.Operand as MethodReference;
if (operand != null)
{
taskMethod = operand;
}
}
}
public static TypeDefinition GetDeclaringType(this MethodDefinition method)
{
var type = method.DeclaringType;
while (type.IsCompilerGenerated() && type.DeclaringType != null)
{
type = type.DeclaringType;
}
return type;
}
public static bool IsCompilerGenerated(this ICustomAttributeProvider value)
{
return value.CustomAttributes
.Any(a => a.AttributeType.Name == "CompilerGeneratedAttribute");
}
public static string GetPreviousLineNumber(this Instruction instruction)
{
while (true)
{
if (instruction.SequencePoint != null)
{
return instruction.SequencePoint.StartLine.ToString();
}
instruction = instruction.Previous;
if (instruction == null)
{
return "?";
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment