From fd1cb641c1e7f670c22b0aa6a3dff40480af9a87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Srbeck=C3=BD?= Date: Tue, 27 Jul 2010 07:56:12 +0000 Subject: [PATCH] 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 --- .../Debugger.Core/MetaData/DebugMethodInfo.cs | 63 ++++++++++++------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs index fb9a330207..e836de362e 100644 --- a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs +++ b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs @@ -284,7 +284,7 @@ namespace Debugger.MetaData if (this.IsPropertyAccessor && this.IsSingleLine) return true; } if (opt.StepOverFieldAccessProperties) { - if (this.IsPropertyAccessor && this.BackingField != null) return true; + if (this.IsPropertyAccessor && this.BackingFieldToken != 0) return true; } return false; } @@ -292,37 +292,55 @@ namespace Debugger.MetaData internal bool IsPropertyAccessor { get; set; } - DebugFieldInfo backingFieldCache; - bool getBackingFieldCalled; + uint backingFieldToken; /// /// Backing field that can be used to obtain the same value as by calling this method. /// + [Tests.Ignore] + public uint BackingFieldToken { + get { + LoadBackingFieldToken(); + return backingFieldToken; + } + } + + /// + /// 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 + /// public DebugFieldInfo BackingField { get { - if (!getBackingFieldCalled) { - backingFieldCache = GetBackingField(); - getBackingFieldCalled = true; - } - return backingFieldCache; + 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;'? - DebugFieldInfo GetBackingField() + bool loadBackingFieldTokenCalled; + + /// Is this method in form 'return this.field;'? + void LoadBackingFieldToken() { - if (this.ParameterCount != 0) return null; + if (loadBackingFieldTokenCalled) return; + loadBackingFieldTokenCalled = true; + + backingFieldToken = 0; + + if (this.ParameterCount != 0) return; ICorDebugCode corCode; try { corCode = this.CorFunction.GetILCode(); - } catch { - return null; + } catch (COMException) { + return; } - if (corCode == null) return null; - if (corCode.IsIL() == 0) return null; - if (corCode.GetSize() > 12) return null; + if (corCode == null || corCode.IsIL() == 0 || corCode.GetSize() > 12) return; List code = new List(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, 0x2A); // ret - if (!success) 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; + if (!success) return; 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 @@ -650,4 +665,4 @@ namespace Debugger.MetaData get { return (DebugType)this.ReturnType; } } } -} +} \ No newline at end of file