|
|
@ -68,11 +68,24 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer |
|
|
|
|
|
|
|
|
|
|
|
return typeUsage ?? method; |
|
|
|
return typeUsage ?? method; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// Given a compiler-generated type, returns the method where that type is used.
|
|
|
|
|
|
|
|
/// Used to detect the 'parent method' for a lambda/iterator/async state machine.
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
public static MethodDefinition GetOriginalCodeLocation(TypeDefinition type) |
|
|
|
public static MethodDefinition GetOriginalCodeLocation(TypeDefinition type) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (type != null && type.DeclaringType != null && type.IsCompilerGenerated()) { |
|
|
|
if (type != null && type.DeclaringType != null && type.IsCompilerGenerated()) { |
|
|
|
MethodDefinition constructor = GetTypeConstructor(type); |
|
|
|
if (type.IsValueType) { |
|
|
|
return FindMethodUsageInType(type.DeclaringType, constructor); |
|
|
|
// Value types might not have any constructor; but they must be stored in a local var
|
|
|
|
|
|
|
|
// because 'initobj' (or 'call .ctor') expects a managed ref.
|
|
|
|
|
|
|
|
return FindVariableOfTypeUsageInType(type.DeclaringType, type); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
MethodDefinition constructor = GetTypeConstructor(type); |
|
|
|
|
|
|
|
if (constructor == null) |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
return FindMethodUsageInType(type.DeclaringType, constructor); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
@ -106,5 +119,26 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static MethodDefinition FindVariableOfTypeUsageInType(TypeDefinition type, TypeDefinition variableType) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
foreach (MethodDefinition method in type.Methods) { |
|
|
|
|
|
|
|
bool found = false; |
|
|
|
|
|
|
|
if (!method.HasBody) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
foreach (var v in method.Body.Variables) { |
|
|
|
|
|
|
|
if (v.VariableType.ResolveWithinSameModule() == variableType) { |
|
|
|
|
|
|
|
found = true; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
method.Body = null; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (found) |
|
|
|
|
|
|
|
return method; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|