Browse Source

Fix #354: NullReferenceException expanding "Read By" node when variable is referenced from an async method.

pull/396/merge
Daniel Grunwald 11 years ago
parent
commit
cfe77638e7
  1. 34
      ILSpy/TreeNodes/Analyzer/Helpers.cs

34
ILSpy/TreeNodes/Analyzer/Helpers.cs

@ -68,12 +68,25 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -68,12 +68,25 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
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)
{
if (type != null && type.DeclaringType != null && type.IsCompilerGenerated()) {
if (type.IsValueType) {
// 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;
}
@ -106,5 +119,26 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -106,5 +119,26 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
}
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;
}
}
}

Loading…
Cancel
Save