Browse Source

Still step over properties in form "return field;" even if the GetBackingField method fails.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@6269 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
David Srbecký 16 years ago
parent
commit
fd1cb641c1
  1. 61
      src/AddIns/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs

61
src/AddIns/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs

@ -284,7 +284,7 @@ namespace Debugger.MetaData
if (this.IsPropertyAccessor && this.IsSingleLine) return true; if (this.IsPropertyAccessor && this.IsSingleLine) return true;
} }
if (opt.StepOverFieldAccessProperties) { if (opt.StepOverFieldAccessProperties) {
if (this.IsPropertyAccessor && this.BackingField != null) return true; if (this.IsPropertyAccessor && this.BackingFieldToken != 0) return true;
} }
return false; return false;
} }
@ -292,37 +292,55 @@ namespace Debugger.MetaData
internal bool IsPropertyAccessor { get; set; } internal bool IsPropertyAccessor { get; set; }
DebugFieldInfo backingFieldCache; uint backingFieldToken;
bool getBackingFieldCalled;
/// <summary> /// <summary>
/// Backing field that can be used to obtain the same value as by calling this method. /// Backing field that can be used to obtain the same value as by calling this method.
/// </summary> /// </summary>
public DebugFieldInfo BackingField { [Tests.Ignore]
public uint BackingFieldToken {
get { get {
if (!getBackingFieldCalled) { LoadBackingFieldToken();
backingFieldCache = GetBackingField(); return backingFieldToken;
getBackingFieldCalled = true; }
} }
return backingFieldCache;
/// <summary>
/// Backing field that can be used to obtain the same value as by calling this method.
/// It works only for fields defined in the class
/// </summary>
public DebugFieldInfo BackingField {
get {
uint token = this.BackingFieldToken;
if (token == 0) return null;
// The token can be a field in different class (static or instance in base class) - so it might not be found in the next call
MemberInfo member;
if (!declaringType.TryGetMember(token, out member)) return null;
return (DebugFieldInfo)member;
} }
} }
// Is this method in form 'return this.field;'? bool loadBackingFieldTokenCalled;
DebugFieldInfo GetBackingField()
/// <summary> Is this method in form 'return this.field;'? </summary>
void LoadBackingFieldToken()
{ {
if (this.ParameterCount != 0) return null; if (loadBackingFieldTokenCalled) return;
loadBackingFieldTokenCalled = true;
backingFieldToken = 0;
if (this.ParameterCount != 0) return;
ICorDebugCode corCode; ICorDebugCode corCode;
try { try {
corCode = this.CorFunction.GetILCode(); corCode = this.CorFunction.GetILCode();
} catch { } catch (COMException) {
return null; return;
} }
if (corCode == null) return null; if (corCode == null || corCode.IsIL() == 0 || corCode.GetSize() > 12) return;
if (corCode.IsIL() == 0) return null;
if (corCode.GetSize() > 12) return null;
List<byte> code = new List<byte>(corCode.GetCode()); List<byte> code = new List<byte>(corCode.GetCode());
@ -335,16 +353,13 @@ namespace Debugger.MetaData
(Read(code, 0x0A, 0x2B, 0x00, 0x06) || true) && // stloc.0; br.s; offset+00; ldloc.0 || nothing (Read(code, 0x0A, 0x2B, 0x00, 0x06) || true) && // stloc.0; br.s; offset+00; ldloc.0 || nothing
Read(code, 0x2A); // ret Read(code, 0x2A); // ret
if (!success) return null; if (!success) return;
// The token can be a field in different class (static or instance in base class) - so it might not be found in the next call
MemberInfo member;
if (!declaringType.TryGetMember(token, out member)) return null;
if (this.Process.Options.Verbose) { if (this.Process.Options.Verbose) {
this.Process.TraceMessage(string.Format("Found backing field for {0}: {1}", this.FullName, member.Name)); this.Process.TraceMessage(string.Format("Found backing field for {0}", this.FullName));
} }
return (DebugFieldInfo)member;
backingFieldToken = token;
} }
// Read expected sequence of bytes // Read expected sequence of bytes

Loading…
Cancel
Save