[mono/monodevelop] [11 commits] f4896b6b: [CorDebug] Move as much code as possible into extension classes.
"Therzok (
[email protected])" <
[email protected]>
Tue, 5 Nov 2013 19:07:23 +0000
| Newsgroups |
gmane.comp.gnome.mono.patches |
| Message-ID |
<0000014229a98008-5fa2c3de-5bf8-4fd3-bf14-93f7296698e5-000000@email.amazonses.com> |
Branch: refs/heads/newCorApi
Home: https://github.com/mono/monodevelop
Compare: https://github.com/mono/monodevelop/compare/31fd6f265712...4d6f4b0516ee
Commit: f4896b6bf42e921bd62d22af645b38312bbff764
Author: Therzok <[email protected]> (Therzok)
Date: 2013-11-05 18:51:46 GMT
URL: https://github.com/mono/monodevelop/commit/f4896b6bf42e921bd62d22af645b38312bbff764
[CorDebug] Move as much code as possible into extension classes.
Changed paths:
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/CorApi2.csproj
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/CorMetadata.cs
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataFieldInfo.cs
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataParameterInfo.cs
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataPropertyInfo.cs
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataType.cs
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/debug/Debugger.cs
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/debug/Process.cs
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/debug/Type.cs
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/debug/Value.cs
M main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorDebuggerSession.cs
M main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorObjectAdaptor.cs
Added paths:
A main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Extensions/DebuggerExtensions.cs
A main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Extensions/MetadataExtensions.cs
A main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Extensions/ProcessExtensions.cs
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/CorApi2.csproj
===================================================================
@@ -23,7 +23,6 @@
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
- <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -119,6 +118,9 @@
<Compile Include="SymStore\SymSearchPolicyAttributes.cs" />
<Compile Include="SymStore\symvariable.cs" />
<Compile Include="SymStore\SymWriter.cs" />
+ <Compile Include="Extensions\MetadataExtensions.cs" />
+ <Compile Include="Extensions\ProcessExtensions.cs" />
+ <Compile Include="Extensions\DebuggerExtensions.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Added: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Extensions/DebuggerExtensions.cs
===================================================================
@@ -0,0 +1,175 @@
+//
+// DebuggerExtensions.cs
+//
+// Author:
+// Therzok <[email protected]>
+//
+// Copyright (c) 2013 Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using Microsoft.Samples.Debugging.CorDebug;
+using Microsoft.Samples.Debugging.CorDebug.NativeApi;
+using Microsoft.Win32.SafeHandles;
+
+namespace Microsoft.Samples.Debugging.Extensions
+{
+ [CLSCompliant (false)]
+ public static class DebuggerExtensions
+ {
+ // [Xamarin] Output redirection.
+ public const int CREATE_REDIRECT_STD = 0x40000000;
+ const string Kernel32LibraryName = "kernel32.dll";
+
+ [
+ DllImport (Kernel32LibraryName, CharSet = CharSet.Auto, SetLastError = true)
+ ]
+ public static extern bool CreatePipe (out SafeFileHandle hReadPipe, out SafeFileHandle hWritePipe, SECURITY_ATTRIBUTES lpPipeAttributes, int nSize);
+
+ [
+ DllImport (Kernel32LibraryName)
+ ]
+ public static extern bool DuplicateHandle (
+ IntPtr hSourceProcessHandle,
+ SafeFileHandle hSourceHandle,
+ IntPtr hTargetProcessHandle,
+ out SafeFileHandle lpTargetHandle,
+ uint dwDesiredAccess,
+ bool bInheritHandle,
+ uint dwOptions
+ );
+
+ const uint DUPLICATE_CLOSE_SOURCE = 0x00000001;
+ const uint DUPLICATE_SAME_ACCESS = 0x00000002;
+
+ [
+ DllImport (Kernel32LibraryName)
+ ]
+ public static extern SafeFileHandle GetStdHandle (uint nStdHandle);
+
+ const uint STD_INPUT_HANDLE = unchecked ((uint)-10);
+ const uint STD_OUTPUT_HANDLE = unchecked ((uint)-11);
+ const uint STD_ERROR_HANDLE = unchecked ((uint)-12);
+
+ [
+ DllImport (Kernel32LibraryName)
+ ]
+ public static extern bool ReadFile (
+ SafeFileHandle hFile,
+ byte[] lpBuffer,
+ int nNumberOfBytesToRead,
+ out int lpNumberOfBytesRead,
+ IntPtr lpOverlapped
+ );
+
+ [
+ DllImport (Kernel32LibraryName, CharSet = CharSet.Auto, SetLastError = true)
+ ]
+ public static extern IntPtr GetCurrentProcess ();
+
+ static void CreateHandles (STARTUPINFO si, out SafeFileHandle outReadPipe, out SafeFileHandle errorReadPipe)
+ {
+ si.dwFlags |= 0x00000100; /* STARTF_USESTDHANDLES*/
+ var sa = new SECURITY_ATTRIBUTES ();
+ sa.bInheritHandle = true;
+ IntPtr curProc = GetCurrentProcess ();
+
+ SafeFileHandle outWritePipe, outReadPipeTmp;
+ if (!CreatePipe (out outReadPipeTmp, out outWritePipe, sa, 0))
+ throw new Exception ("Pipe creation failed");
+
+ // Create the child error pipe.
+ SafeFileHandle errorWritePipe, errorReadPipeTmp;
+ if (!CreatePipe (out errorReadPipeTmp, out errorWritePipe, sa, 0))
+ throw new Exception ("Pipe creation failed");
+
+ // Create new output read and error read handles. Set
+ // the Properties to FALSE. Otherwise, the child inherits the
+ // properties and, as a result, non-closeable handles to the pipes
+ // are created.
+ if (!DuplicateHandle (curProc, outReadPipeTmp, curProc, out outReadPipe, 0, false, DUPLICATE_SAME_ACCESS))
+ throw new Exception ("Pipe creation failed");
+ if (!DuplicateHandle (curProc, errorReadPipeTmp, curProc, out errorReadPipe, 0, false, DUPLICATE_SAME_ACCESS))
+ throw new Exception ("Pipe creation failed");
+
+ NativeMethods.CloseHandle (curProc);
+
+ // Close inheritable copies of the handles you do not want to be
+ // inherited.
+ outReadPipeTmp.Close ();
+ errorReadPipeTmp.Close ();
+
+ si.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
+ si.hStdOutput = outWritePipe;
+ si.hStdError = errorWritePipe;
+ }
+
+ internal static void SetupOutputRedirection (STARTUPINFO si, ref int flags, SafeFileHandle outReadPipe, SafeFileHandle errorReadPipe)
+ {
+ if ((flags & CREATE_REDIRECT_STD) != 0) {
+ CreateHandles (si, out outReadPipe, out errorReadPipe);
+ flags &= ~CREATE_REDIRECT_STD;
+ }
+ else {
+ si.hStdInput = new SafeFileHandle (IntPtr.Zero, false);
+ si.hStdOutput = new SafeFileHandle (IntPtr.Zero, false);
+ si.hStdError = new SafeFileHandle (IntPtr.Zero, false);
+ }
+ }
+
+ internal static void TearDownOutputRedirection (SafeFileHandle outReadPipe, SafeFileHandle errorReadPipe, STARTUPINFO si, CorProcess ret)
+ {
+ if (outReadPipe != null) {
+ // Close pipe handles (do not continue to modify the parent).
+ // You need to make sure that no handles to the write end of the
+ // output pipe are maintained in this process or else the pipe will
+ // not close when the child process exits and the ReadFile will hang.
+
+ si.hStdInput.Close ();
+ si.hStdOutput.Close ();
+ si.hStdError.Close ();
+
+ ret.TrackStdOutput (outReadPipe, errorReadPipe);
+ }
+ }
+
+ internal static IntPtr SetupEnvironment (IDictionary<string, string> environment)
+ {
+ IntPtr env = IntPtr.Zero;
+ if (environment != null) {
+ string senv = null;
+ foreach (KeyValuePair<string, string> var in environment) {
+ senv += var.Key + "=" + var.Value + "\0";
+ }
+ senv += "\0";
+ env = Marshal.StringToHGlobalAnsi (senv);
+ }
+ return env;
+ }
+
+ internal static void TearDownEnvironment (IntPtr env)
+ {
+ if (env != IntPtr.Zero)
+ Marshal.FreeHGlobal (env);
+ }
+ }
+}
+
Added: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Extensions/MetadataExtensions.cs
===================================================================
@@ -0,0 +1,342 @@
+//
+// MetadataExtensions.cs
+//
+// Author:
+// Lluis Sanchez <[email protected]>
+// Therzok <[email protected]>
+//
+// Copyright (c) 2013 Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using Microsoft.Samples.Debugging.CorDebug.NativeApi;
+using Microsoft.Samples.Debugging.CorMetadata;
+using Microsoft.Samples.Debugging.CorMetadata.NativeApi;
+
+namespace Microsoft.Samples.Debugging.Extensions
+{
+ // [Xamarin] Expression evaluator.
+ public static class MetadataExtensions
+ {
+ internal static bool TypeFlagsMatch (bool isPublic, bool isStatic, BindingFlags flags)
+ {
+ if (isPublic && (flags & BindingFlags.Public) == 0)
+ return false;
+ if (!isPublic && (flags & BindingFlags.NonPublic) == 0)
+ return false;
+ if (isStatic && (flags & BindingFlags.Static) == 0)
+ return false;
+ if (!isStatic && (flags & BindingFlags.Instance) == 0)
+ return false;
+ return true;
+ }
+
+ internal static Type MakeDelegate (Type retType, List<Type> argTypes)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public static Type MakeArray (Type t, List<int> sizes, List<int> loBounds)
+ {
+ var mt = t as MetadataType;
+ if (mt != null) {
+ if (sizes == null) {
+ sizes = new List<int> ();
+ sizes.Add (1);
+ }
+ mt.m_arraySizes = sizes;
+ mt.m_arrayLoBounds = loBounds;
+ return mt;
+ }
+ if (sizes == null || sizes.Count == 1)
+ return t.MakeArrayType ();
+ return t.MakeArrayType (sizes.Capacity);
+ }
+
+ public static Type MakeByRef (Type t)
+ {
+ var mt = t as MetadataType;
+ if (mt != null) {
+ mt.m_isByRef = true;
+ return mt;
+ }
+ return t.MakeByRefType ();
+ }
+
+ public static Type MakePointer (Type t)
+ {
+ var mt = t as MetadataType;
+ if (mt != null) {
+ mt.m_isPtr = true;
+ return mt;
+ }
+ return t.MakeByRefType ();
+ }
+
+ public static Type MakeGeneric (Type t, List<Type> typeArgs)
+ {
+ var mt = (MetadataType)t;
+ mt.m_typeArgs = typeArgs;
+ return mt;
+ }
+ }
+
+ // [Xamarin] Expression evaluator.
+ [CLSCompliant (false)]
+ public static class MetadataHelperFunctionsExtensions
+ {
+ public static Dictionary<CorElementType, Type> CoreTypes = new Dictionary<CorElementType, Type> ();
+ static MetadataHelperFunctionsExtensions ()
+ {
+ CoreTypes.Add (CorElementType.ELEMENT_TYPE_BOOLEAN, typeof (bool));
+ CoreTypes.Add (CorElementType.ELEMENT_TYPE_CHAR, typeof (char));
+ CoreTypes.Add (CorElementType.ELEMENT_TYPE_I1, typeof (sbyte));
+ CoreTypes.Add (CorElementType.ELEMENT_TYPE_U1, typeof (byte));
+ CoreTypes.Add (CorElementType.ELEMENT_TYPE_I2, typeof (short));
+ CoreTypes.Add (CorElementType.ELEMENT_TYPE_U2, typeof (ushort));
+ CoreTypes.Add (CorElementType.ELEMENT_TYPE_I4, typeof (int));
+ CoreTypes.Add (CorElementType.ELEMENT_TYPE_U4, typeof (uint));
+ CoreTypes.Add (CorElementType.ELEMENT_TYPE_I8, typeof (long));
+ CoreTypes.Add (CorElementType.ELEMENT_TYPE_U8, typeof (ulong));
+ CoreTypes.Add (CorElementType.ELEMENT_TYPE_R4, typeof (float));
+ CoreTypes.Add (CorElementType.ELEMENT_TYPE_R8, typeof (double));
+ CoreTypes.Add (CorElementType.ELEMENT_TYPE_STRING, typeof (string));
+ CoreTypes.Add (CorElementType.ELEMENT_TYPE_I, typeof (IntPtr));
+ CoreTypes.Add (CorElementType.ELEMENT_TYPE_U, typeof (UIntPtr));
+ }
+
+ internal static void ReadMethodSignature (IMetadataImport importer, ref IntPtr pData, out CorCallingConvention cconv, out Type retType, out List<Type> argTypes)
+ {
+ cconv = MetadataHelperFunctions.CorSigUncompressCallingConv (ref pData);
+ uint numArgs = 0;
+ // FIXME: Use number of <T>s.
+ uint types = 0;
+ if ((cconv & CorCallingConvention.Generic) == CorCallingConvention.Generic)
+ types = MetadataHelperFunctions.CorSigUncompressData (ref pData);
+
+ if (cconv != CorCallingConvention.Field)
+ numArgs = MetadataHelperFunctions.CorSigUncompressData (ref pData);
+
+ retType = ReadType (importer, ref pData);
+ argTypes = new List<Type> ();
+ for (int n = 0; n < numArgs; n++)
+ argTypes.Add (ReadType (importer, ref pData));
+ }
+
+ class GenericType
+ {
+ // Used as marker for generic method args
+ }
+
+ static Type ReadType (IMetadataImport importer, ref IntPtr pData)
+ {
+ CorElementType et;
+ unsafe {
+ var pBytes = (byte*)pData;
+ et = (CorElementType) (*pBytes);
+ pData = (IntPtr) (pBytes + 1);
+ }
+
+ switch (et)
+ {
+ case CorElementType.ELEMENT_TYPE_VOID: return typeof (void);
+ case CorElementType.ELEMENT_TYPE_BOOLEAN: return typeof (bool);
+ case CorElementType.ELEMENT_TYPE_CHAR: return typeof (char);
+ case CorElementType.ELEMENT_TYPE_I1: return typeof (sbyte);
+ case CorElementType.ELEMENT_TYPE_U1: return typeof (byte);
+ case CorElementType.ELEMENT_TYPE_I2: return typeof (short);
+ case CorElementType.ELEMENT_TYPE_U2: return typeof (ushort);
+ case CorElementType.ELEMENT_TYPE_I4: return typeof (int);
+ case CorElementType.ELEMENT_TYPE_U4: return typeof (uint);
+ case CorElementType.ELEMENT_TYPE_I8: return typeof (long);
+ case CorElementType.ELEMENT_TYPE_U8: return typeof (ulong);
+ case CorElementType.ELEMENT_TYPE_R4: return typeof (float);
+ case CorElementType.ELEMENT_TYPE_R8: return typeof (double);
+ case CorElementType.ELEMENT_TYPE_STRING: return typeof (string);
+ case CorElementType.ELEMENT_TYPE_I: return typeof (IntPtr);
+ case CorElementType.ELEMENT_TYPE_U: return typeof (UIntPtr);
+ case CorElementType.ELEMENT_TYPE_OBJECT: return typeof (object);
+
+ case CorElementType.ELEMENT_TYPE_VAR:
+ case CorElementType.ELEMENT_TYPE_MVAR:
+ // Generic args in methods not supported. Return a dummy type.
+ MetadataHelperFunctions.CorSigUncompressData (ref pData);
+ return typeof(GenericType);
+
+ case CorElementType.ELEMENT_TYPE_GENERICINST: {
+ Type t = ReadType (importer, ref pData);
+ var typeArgs = new List<Type> ();
+ uint num = MetadataHelperFunctions.CorSigUncompressData (ref pData);
+ for (int n=0; n<num; n++) {
+ typeArgs.Add (ReadType (importer, ref pData));
+ }
+ return MetadataExtensions.MakeGeneric (t, typeArgs);
+ }
+
+ case CorElementType.ELEMENT_TYPE_PTR: {
+ Type t = ReadType (importer, ref pData);
+ return MetadataExtensions.MakePointer (t);
+ }
+
+ case CorElementType.ELEMENT_TYPE_BYREF: {
+ Type t = ReadType (importer, ref pData);
+ return MetadataExtensions.MakeByRef(t);
+ }
+
+ case CorElementType.ELEMENT_TYPE_END:
+ case CorElementType.ELEMENT_TYPE_VALUETYPE:
+ case CorElementType.ELEMENT_TYPE_CLASS: {
+ uint token = MetadataHelperFunctions.CorSigUncompressToken (ref pData);
+ return new MetadataType (importer, (int) token);
+ }
+
+ case CorElementType.ELEMENT_TYPE_ARRAY: {
+ Type t = ReadType (importer, ref pData);
+ int rank = (int)MetadataHelperFunctions.CorSigUncompressData (ref pData);
+ if (rank == 0)
+ return MetadataExtensions.MakeArray (t, null, null);
+
+ uint numSizes = MetadataHelperFunctions.CorSigUncompressData (ref pData);
+ var sizes = new List<int> (rank);
+ for (int n = 0; n < numSizes && n < rank; n++)
+ sizes.Add ((int)MetadataHelperFunctions.CorSigUncompressData (ref pData));
+
+ uint numLoBounds = MetadataHelperFunctions.CorSigUncompressData (ref pData);
+ var loBounds = new List<int> (rank);
+ for (int n = 0; n < numLoBounds && n < rank; n++)
+ loBounds.Add ((int)MetadataHelperFunctions.CorSigUncompressData (ref pData));
+
+ return MetadataExtensions.MakeArray (t, sizes, loBounds);
+ }
+
+ case CorElementType.ELEMENT_TYPE_SZARRAY: {
+ Type t = ReadType (importer, ref pData);
+ return MetadataExtensions.MakeArray (t, null, null);
+ }
+
+ case CorElementType.ELEMENT_TYPE_FNPTR: {
+ CorCallingConvention cconv;
+ Type retType;
+ List<Type> argTypes;
+ ReadMethodSignature (importer, ref pData, out cconv, out retType, out argTypes);
+ return MetadataExtensions.MakeDelegate (retType, argTypes);
+ }
+
+ case CorElementType.ELEMENT_TYPE_CMOD_REQD:
+ case CorElementType.ELEMENT_TYPE_CMOD_OPT:
+ return ReadType (importer, ref pData);
+ }
+ throw new NotSupportedException ("Unknown sig element type: " + et);
+ }
+
+ static readonly object[] emptyAttributes = new object[0];
+
+ static internal object[] GetDebugAttributes (IMetadataImport importer, int token)
+ {
+ var attributes = new ArrayList ();
+ object attr = GetCustomAttribute (importer, token, typeof (System.Diagnostics.DebuggerTypeProxyAttribute));
+ if (attr != null)
+ attributes.Add (attr);
+ attr = GetCustomAttribute (importer, token, typeof (System.Diagnostics.DebuggerDisplayAttribute));
+ if (attr != null)
+ attributes.Add (attr);
+ attr = GetCustomAttribute (importer, token, typeof (System.Diagnostics.DebuggerBrowsableAttribute));
+ if (attr != null)
+ attributes.Add (attr);
+ attr = GetCustomAttribute (importer, token, typeof (System.Runtime.CompilerServices.CompilerGeneratedAttribute));
+ if (attr != null)
+ attributes.Add (attr);
+
+ return attributes.Count == 0 ? emptyAttributes : attributes.ToArray ();
+ }
+
+ // [Xamarin] Expression evaluator.
+ static internal object GetCustomAttribute (IMetadataImport importer, int token, Type type)
+ {
+ uint sigSize;
+ IntPtr ppvSig;
+ int hr = importer.GetCustomAttributeByName (token, type.FullName, out ppvSig, out sigSize);
+ if (hr != 0)
+ return null;
+
+ var data = new byte[sigSize];
+ Marshal.Copy (ppvSig, data, 0, (int)sigSize);
+ var br = new BinaryReader (new MemoryStream (data));
+
+ // Prolog
+ if (br.ReadUInt16 () != 1)
+ throw new InvalidOperationException ("Incorrect attribute prolog");
+
+ ConstructorInfo ctor = type.GetConstructors ()[0];
+ ParameterInfo[] pars = ctor.GetParameters ();
+
+ var args = new object[pars.Length];
+
+ // Fixed args
+ for (int n=0; n<pars.Length; n++)
+ args [n] = ReadValue (br, pars[n].ParameterType);
+
+ object ob = Activator.CreateInstance (type, args);
+
+ // Named args
+ uint nargs = br.ReadUInt16 ();
+ for (; nargs > 0; nargs--) {
+ byte fieldOrProp = br.ReadByte ();
+ byte atype = br.ReadByte ();
+
+ // Boxed primitive
+ if (atype == 0x51)
+ atype = br.ReadByte ();
+ var et = (CorElementType) atype;
+ string pname = br.ReadString ();
+ object val = ReadValue (br, CoreTypes [et]);
+
+ if (fieldOrProp == 0x53) {
+ FieldInfo fi = type.GetField (pname);
+ fi.SetValue (ob, val);
+ }
+ else {
+ PropertyInfo pi = type.GetProperty (pname);
+ pi.SetValue (ob, val, null);
+ }
+ }
+ return ob;
+ }
+
+ // [Xamarin] Expression evaluator.
+ static object ReadValue (BinaryReader br, Type type)
+ {
+ if (type.IsEnum) {
+ object ob = ReadValue (br, Enum.GetUnderlyingType (type));
+ return Enum.ToObject (type, Convert.ToInt64 (ob));
+ }
+ if (type == typeof (string) || type == typeof(Type))
+ return br.ReadString ();
+ if (type == typeof (int))
+ return br.ReadInt32 ();
+ throw new InvalidOperationException ("Can't parse value of type: " + type);
+ }
+ }
+}
+
Added: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Extensions/ProcessExtensions.cs
===================================================================
@@ -0,0 +1,117 @@
+//
+// ProcessExtensions.cs
+//
+// Author:
+// Lluis Sanchez <[email protected]>
+// Therzok <[email protected]>
+//
+// Copyright (c) 2013 Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using Microsoft.Samples.Debugging.CorDebug;
+using Microsoft.Win32.SafeHandles;
+
+namespace Microsoft.Samples.Debugging.Extensions
+{
+ // [Xamarin] Output redirection.
+ public class CorTargetOutputEventArgs: EventArgs
+ {
+ public CorTargetOutputEventArgs (string text, bool isStdError)
+ {
+ Text = text;
+ IsStdError = isStdError;
+ }
+
+ public string Text { get; set; }
+
+ public bool IsStdError { get; set; }
+ }
+
+ public delegate void CorTargetOutputEventHandler (Object sender, CorTargetOutputEventArgs e);
+
+ public static class CorProcessExtensions
+ {
+ internal static void TrackStdOutput (this CorProcess proc, SafeFileHandle outputPipe, SafeFileHandle errorPipe)
+ {
+ var outputReader = new Thread (delegate () {
+ proc.ReadOutput (outputPipe, false);
+ });
+ outputReader.Name = "Debugger output reader";
+ outputReader.IsBackground = true;
+ outputReader.Start ();
+
+ var errorReader = new Thread (delegate () {
+ proc.ReadOutput (errorPipe, true);
+ });
+ errorReader.Name = "Debugger error reader";
+ errorReader.IsBackground = true;
+ errorReader.Start ();
+ }
+
+ // [Xamarin] Output redirection.
+ static void ReadOutput (this CorProcess proc, SafeFileHandle pipe, bool isStdError)
+ {
+ var buffer = new byte[256];
+ int nBytesRead;
+
+ try {
+ while (true) {
+ if (!DebuggerExtensions.ReadFile (pipe, buffer, buffer.Length, out nBytesRead, IntPtr.Zero) || nBytesRead == 0)
+ break; // pipe done - normal exit path.
+
+ string s = System.Text.Encoding.Default.GetString (buffer, 0, nBytesRead);
+ if (OnStdOutput != null)
+ OnStdOutput (proc, new CorTargetOutputEventArgs (s, isStdError));
+ }
+ } catch {
+ }
+ }
+
+ public static void RegisterStdOutput (this CorProcess proc, CorTargetOutputEventHandler handler)
+ {
+ proc.OnProcessExit += delegate {
+ RemoveEventsFor (proc);
+ };
+
+ List<CorTargetOutputEventHandler> list;
+ if (!events.TryGetValue (proc, out list))
+ list = new List<CorTargetOutputEventHandler> ();
+ list.Add (handler);
+
+ events [proc] = list;
+ OnStdOutput += handler;
+ }
+
+ static void RemoveEventsFor (CorProcess proc)
+ {
+ foreach (CorTargetOutputEventHandler handler in events [proc])
+ OnStdOutput -= handler;
+
+ events.Remove (proc);
+ }
+
+ // [Xamarin] Output redirection.
+ static event CorTargetOutputEventHandler OnStdOutput;
+ static readonly Dictionary<CorProcess, List<CorTargetOutputEventHandler>> events = new Dictionary<CorProcess, List<CorTargetOutputEventHandler>> ();
+ }
+}
+
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/CorMetadata.cs
===================================================================
@@ -4,46 +4,23 @@
// Copyright (C) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------
using System;
-using System.IO;
using System.Reflection;
using System.Text;
using System.Runtime.InteropServices;
using System.Globalization;
using System.Collections;
-using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Samples.Debugging.CorDebug;
using Microsoft.Samples.Debugging.CorMetadata.NativeApi;
using Microsoft.Samples.Debugging.CorDebug.NativeApi;
+using Microsoft.Samples.Debugging.Extensions;
+using System.Collections.Generic;
namespace Microsoft.Samples.Debugging.CorMetadata
{
public sealed class CorMetadataImport
{
- // [Xamarin] Expression evaluator.
- public static Dictionary<CorElementType, Type> CoreTypes = new Dictionary<CorElementType, Type> ();
-
- // [Xamarin] Expression evaluator.
- static CorMetadataImport ()
- {
- CoreTypes.Add (CorElementType.ELEMENT_TYPE_BOOLEAN, typeof (bool));
- CoreTypes.Add (CorElementType.ELEMENT_TYPE_CHAR, typeof (char));
- CoreTypes.Add (CorElementType.ELEMENT_TYPE_I1, typeof (sbyte));
- CoreTypes.Add (CorElementType.ELEMENT_TYPE_U1, typeof (byte));
- CoreTypes.Add (CorElementType.ELEMENT_TYPE_I2, typeof (short));
- CoreTypes.Add (CorElementType.ELEMENT_TYPE_U2, typeof (ushort));
- CoreTypes.Add (CorElementType.ELEMENT_TYPE_I4, typeof (int));
- CoreTypes.Add (CorElementType.ELEMENT_TYPE_U4, typeof (uint));
- CoreTypes.Add (CorElementType.ELEMENT_TYPE_I8, typeof (long));
- CoreTypes.Add (CorElementType.ELEMENT_TYPE_U8, typeof (ulong));
- CoreTypes.Add (CorElementType.ELEMENT_TYPE_R4, typeof (float));
- CoreTypes.Add (CorElementType.ELEMENT_TYPE_R8, typeof (double));
- CoreTypes.Add (CorElementType.ELEMENT_TYPE_STRING, typeof (string));
- CoreTypes.Add (CorElementType.ELEMENT_TYPE_I, typeof (IntPtr));
- CoreTypes.Add (CorElementType.ELEMENT_TYPE_U, typeof (UIntPtr));
- }
-
public CorMetadataImport(CorModule managedModule)
{
m_importer = managedModule.GetMetaDataInterface <IMetadataImport>();
@@ -326,8 +303,8 @@ internal MetadataMethodInfo(IMetadataImport importer,int methodToken)
// [Xamarin] Expression evaluator.
CorCallingConvention callingConv;
- MetadataHelperFunctions.ReadMethodSignature (importer, ref ppvSigBlob, out callingConv, out m_retType, out m_argTypes);
- m_name = szMethodName.ToString ();
+ MetadataHelperFunctionsExtensions.ReadMethodSignature (importer, ref ppvSigBlob, out callingConv, out m_retType, out m_argTypes);
+ m_name = szMethodName.ToString();
m_methodAttributes = (MethodAttributes)pdwAttr;
}
@@ -437,10 +414,11 @@ public override System.Reflection.ParameterInfo[] GetParameters()
m_methodToken, out paramToken,1,out count);
if(count!=1)
break;
- MetadataParameterInfo mp = new MetadataParameterInfo (m_importer, paramToken,
- this, DeclaringType, m_argTypes [nArg++]);
- if (mp.Name != string.Empty)
- al.Add(mp);
+ var mp = new MetadataParameterInfo (m_importer, paramToken, this, m_argTypes [nArg++]);
+ if (mp.Name != String.Empty)
+ al.Add (mp);
+ //al.Add(new MetadataParameterInfo(m_importer,paramToken,
+ // this,DeclaringType));
}
}
finally
@@ -471,7 +449,7 @@ public string[] GetGenericArgumentNames()
// [Xamarin] Expression evaluator.
private List<Type> m_argTypes;
private Type m_retType;
- }
+ }
public enum MetadataTokenType
{
@@ -594,133 +572,6 @@ static class MetadataHelperFunctions
{
private static uint TokenFromRid(uint rid, uint tktype) {return (rid) | (tktype);}
- // [Xamarin] Expression evaluator.
- public static void ReadMethodSignature (IMetadataImport importer, ref IntPtr pData, out CorCallingConvention cconv, out Type retType, out List<Type> argTypes)
- {
- cconv = MetadataHelperFunctions.CorSigUncompressCallingConv (ref pData);
- uint numArgs = 0;
- // FIXME: Use number of <T>s.
- uint types = 0;
- if ((cconv & CorCallingConvention.Generic) == CorCallingConvention.Generic)
- types = MetadataHelperFunctions.CorSigUncompressData (ref pData);
-
- if (cconv != CorCallingConvention.Field)
- numArgs = MetadataHelperFunctions.CorSigUncompressData (ref pData);
-
- retType = MetadataHelperFunctions.ReadType (importer, ref pData);
- argTypes = new List<Type> ();
- for (int n = 0; n < numArgs; n++)
- argTypes.Add (MetadataHelperFunctions.ReadType (importer, ref pData));
- }
-
- // [Xamarin] Expression evaluator.
- class GenericType
- {
- // Used as marker for generic method args
- }
-
- // [Xamarin] Expression evaluator.
- static Type ReadType (IMetadataImport importer, ref IntPtr pData)
- {
- CorElementType et;
- unsafe {
- byte* pBytes = (byte*)pData;
- et = (CorElementType) (*pBytes);
- pData = (IntPtr) (pBytes + 1);
- }
-
- switch (et)
- {
- case CorElementType.ELEMENT_TYPE_VOID: return typeof (void);
- case CorElementType.ELEMENT_TYPE_BOOLEAN: return typeof (bool);
- case CorElementType.ELEMENT_TYPE_CHAR: return typeof (char);
- case CorElementType.ELEMENT_TYPE_I1: return typeof (sbyte);
- case CorElementType.ELEMENT_TYPE_U1: return typeof (byte);
- case CorElementType.ELEMENT_TYPE_I2: return typeof (short);
- case CorElementType.ELEMENT_TYPE_U2: return typeof (ushort);
- case CorElementType.ELEMENT_TYPE_I4: return typeof (int);
- case CorElementType.ELEMENT_TYPE_U4: return typeof (uint);
- case CorElementType.ELEMENT_TYPE_I8: return typeof (long);
- case CorElementType.ELEMENT_TYPE_U8: return typeof (ulong);
- case CorElementType.ELEMENT_TYPE_R4: return typeof (float);
- case CorElementType.ELEMENT_TYPE_R8: return typeof (double);
- case CorElementType.ELEMENT_TYPE_STRING: return typeof (string);
- case CorElementType.ELEMENT_TYPE_I: return typeof (IntPtr);
- case CorElementType.ELEMENT_TYPE_U: return typeof (UIntPtr);
- case CorElementType.ELEMENT_TYPE_OBJECT: return typeof (object);
-
- case CorElementType.ELEMENT_TYPE_VAR:
- case CorElementType.ELEMENT_TYPE_MVAR:
- // Generic args in methods not supported. Return a dummy type.
- CorSigUncompressData (ref pData);
- return typeof(GenericType);
-
- case CorElementType.ELEMENT_TYPE_GENERICINST: {
- Type t = ReadType (importer, ref pData);
- List<Type> typeArgs = new List<Type> ();
- uint num = CorSigUncompressData (ref pData);
- for (int n=0; n<num; n++) {
- typeArgs.Add (ReadType (importer, ref pData));
- }
- return MetadataType.MakeGeneric (t, typeArgs);
- }
-
- case CorElementType.ELEMENT_TYPE_PTR: {
- Type t = ReadType (importer, ref pData);
- return MetadataType.MakePointer (t);
- }
-
- case CorElementType.ELEMENT_TYPE_BYREF: {
- Type t = ReadType (importer, ref pData);
- return MetadataType.MakeByRef(t);
- }
-
- case CorElementType.ELEMENT_TYPE_END:
- case CorElementType.ELEMENT_TYPE_VALUETYPE:
- case CorElementType.ELEMENT_TYPE_CLASS: {
- uint token = CorSigUncompressToken (ref pData);
- return new MetadataType (importer, (int) token);
- }
-
- case CorElementType.ELEMENT_TYPE_ARRAY: {
- Type t = ReadType (importer, ref pData);
- int rank = (int)CorSigUncompressData (ref pData);
- if (rank == 0)
- return MetadataType.MakeArray (t, null, null);
-
- uint numSizes = CorSigUncompressData (ref pData);
- var sizes = new List<int> (rank);
- for (int n = 0; n < numSizes && n < rank; n++)
- sizes.Add ((int)CorSigUncompressData (ref pData));
-
- uint numLoBounds = CorSigUncompressData (ref pData);
- var loBounds = new List<int> (rank);
- for (int n = 0; n < numLoBounds && n < rank; n++)
- loBounds.Add ((int)CorSigUncompressData (ref pData));
-
- return MetadataType.MakeArray (t, sizes, loBounds);
- }
-
- case CorElementType.ELEMENT_TYPE_SZARRAY: {
- Type t = ReadType (importer, ref pData);
- return MetadataType.MakeArray (t, null, null);
- }
-
- case CorElementType.ELEMENT_TYPE_FNPTR: {
- CorCallingConvention cconv;
- Type retType;
- List<Type> argTypes;
- ReadMethodSignature (importer, ref pData, out cconv, out retType, out argTypes);
- return MetadataType.MakeDelegate (retType, argTypes);
- }
-
- case CorElementType.ELEMENT_TYPE_CMOD_REQD:
- case CorElementType.ELEMENT_TYPE_CMOD_OPT:
- return ReadType (importer, ref pData);
- }
- throw new NotSupportedException ("Unknown sig element type: " + et);
- }
-
// The below have been translated manually from the inline C++ helpers in cor.h
internal static uint CorSigUncompressBigData(
@@ -980,97 +831,6 @@ static Type ReadType (IMetadataImport importer, ref IntPtr pData)
}
return genargs;
}
+ }
- // [Xamarin] Expression evaluator.
- static object[] emptyAttributes = new object[0];
-
- static internal object[] GetDebugAttributes (IMetadataImport importer, int token)
- {
- ArrayList attributes = new ArrayList ();
- object attr = MetadataHelperFunctions.GetCustomAttribute (importer, token, typeof (System.Diagnostics.DebuggerTypeProxyAttribute));
- if (attr != null)
- attributes.Add (attr);
- attr = MetadataHelperFunctions.GetCustomAttribute (importer, token, typeof (System.Diagnostics.DebuggerDisplayAttribute));
- if (attr != null)
- attributes.Add (attr);
- attr = MetadataHelperFunctions.GetCustomAttribute (importer, token, typeof (System.Diagnostics.DebuggerBrowsableAttribute));
- if (attr != null)
- attributes.Add (attr);
- attr = MetadataHelperFunctions.GetCustomAttribute (importer, token, typeof (System.Runtime.CompilerServices.CompilerGeneratedAttribute));
- if (attr != null)
- attributes.Add (attr);
-
- if (attributes.Count == 0)
- return emptyAttributes;
- else
- return attributes.ToArray ();
- }
-
- // [Xamarin] Expression evaluator.
- static internal object GetCustomAttribute (IMetadataImport importer, int token, Type type)
- {
- uint sigSize = 0;
- IntPtr ppvSig = IntPtr.Zero;
- int hr = importer.GetCustomAttributeByName (token, type.FullName, out ppvSig, out sigSize);
- if (hr != 0)
- return null;
-
- byte[] data = new byte[sigSize];
- Marshal.Copy (ppvSig, data, 0, (int)sigSize);
- BinaryReader br = new BinaryReader (new MemoryStream (data));
-
- // Prolog
- if (br.ReadUInt16 () != 1)
- throw new InvalidOperationException ("Incorrect attribute prolog");
-
- ConstructorInfo ctor = type.GetConstructors ()[0];
- ParameterInfo[] pars = ctor.GetParameters ();
-
- object[] args = new object[pars.Length];
-
- // Fixed args
- for (int n=0; n<pars.Length; n++)
- args [n] = ReadValue (br, pars[n].ParameterType);
-
- object ob = Activator.CreateInstance (type, args);
-
- // Named args
- uint nargs = br.ReadUInt16 ();
- for (; nargs > 0; nargs--) {
- byte fieldOrProp = br.ReadByte ();
- byte atype = br.ReadByte ();
-
- // Boxed primitive
- if (atype == 0x51)
- atype = br.ReadByte ();
- CorElementType et = (CorElementType) atype;
- string pname = br.ReadString ();
- object val = ReadValue (br, CorMetadataImport.CoreTypes[et]);
-
- if (fieldOrProp == 0x53) {
- FieldInfo fi = type.GetField (pname);
- fi.SetValue (ob, val);
- }
- else {
- PropertyInfo pi = type.GetProperty (pname);
- pi.SetValue (ob, val, null);
- }
- }
- return ob;
- }
-
- // [Xamarin] Expression evaluator.
- static object ReadValue (BinaryReader br, Type type)
- {
- if (type.IsEnum) {
- object ob = ReadValue (br, Enum.GetUnderlyingType (type));
- return Enum.ToObject (type, Convert.ToInt64 (ob));
- }
- if (type == typeof (string) || type == typeof(Type))
- return br.ReadString ();
- if (type == typeof (int))
- return br.ReadInt32 ();
- throw new InvalidOperationException ("Can't parse value of type: " + type);
- }
- }
} // namspace Microsoft.Debugger.MetadataWrapper
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataFieldInfo.cs
===================================================================
@@ -14,6 +14,7 @@
using Microsoft.Samples.Debugging.CorDebug;
using Microsoft.Samples.Debugging.CorMetadata.NativeApi;
using Microsoft.Samples.Debugging.CorDebug.NativeApi;
+using Microsoft.Samples.Debugging.Extensions;
namespace Microsoft.Samples.Debugging.CorMetadata
{
@@ -66,8 +67,8 @@ out pcchValue
m_value = ParseDefaultValue(declaringType,ppvSigBlob,ppvRawValue);
}
// [Xamarin] Expression evaluator.
- MetadataHelperFunctions.GetCustomAttribute (importer, m_fieldToken, typeof (System.Diagnostics.DebuggerBrowsableAttribute));
- }
+ MetadataHelperFunctionsExtensions.GetCustomAttribute (m_importer, m_fieldToken, typeof (DebuggerBrowsableAttribute));
+ }
private static object ParseDefaultValue(MetadataType declaringType, IntPtr ppvSigBlob, IntPtr ppvRawValue)
{
@@ -76,7 +77,9 @@ private static object ParseDefaultValue(MetadataType declaringType, IntPtr ppvSi
Debug.Assert(callingConv == CorCallingConvention.Field);
CorElementType elementType = MetadataHelperFunctions.CorSigUncompressElementType(ref ppvSigTemp);
+ // TODO: Check this:
if (elementType == CorElementType.ELEMENT_TYPE_END || elementType == CorElementType.ELEMENT_TYPE_VALUETYPE)
+ //if (elementType == CorElementType.ELEMENT_TYPE_VALUETYPE)
{
uint token = MetadataHelperFunctions.CorSigUncompressToken(ref ppvSigTemp);
@@ -148,9 +151,11 @@ public override void SetValue(Object obj, Object value,BindingFlags invokeAttr,B
}
// [Xamarin] Expression evaluator.
- public override bool IsDefined (Type attributeType, bool inherit)
+ public override object[] GetCustomAttributes (bool inherit)
{
- return GetCustomAttributes (attributeType, inherit).Length > 0;
+ if (m_customAttributes == null)
+ m_customAttributes = MetadataHelperFunctionsExtensions.GetDebugAttributes (m_importer, m_fieldToken);
+ return m_customAttributes;
}
// [Xamarin] Expression evaluator.
@@ -165,11 +170,9 @@ public override object[] GetCustomAttributes (Type attributeType, bool inherit)
}
// [Xamarin] Expression evaluator.
- public override object[] GetCustomAttributes (bool inherit)
+ public override bool IsDefined (Type attributeType, bool inherit)
{
- if (m_customAttributes == null)
- m_customAttributes = MetadataHelperFunctions.GetDebugAttributes (m_importer, m_fieldToken);
- return m_customAttributes;
+ return GetCustomAttributes (attributeType, inherit).Length > 0;
}
@@ -246,5 +249,5 @@ public override int MetadataToken
private Object m_value;
// [Xamarin] Expression evaluator.
private object[] m_customAttributes;
- }
+ }
}
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataParameterInfo.cs
===================================================================
@@ -19,9 +19,8 @@ namespace Microsoft.Samples.Debugging.CorMetadata
{
public sealed class MetadataParameterInfo : ParameterInfo
{
- // [Xamarin] Expression evaluator.
internal MetadataParameterInfo(IMetadataImport importer,int paramToken,
- MemberInfo memberImpl,Type typeImpl, Type argType)
+ MemberInfo memberImpl,Type typeImpl)
{
int parentToken;
uint pulSequence,pdwAttr,pdwCPlusTypeFlag,pcchValue,size;
@@ -51,8 +50,7 @@ out pcchValue
out pcchValue
);
NameImpl = szName.ToString();
- // [Xamarin] Expression evaluator.
- ClassImpl = argType;
+ ClassImpl = typeImpl;
PositionImpl = (int)pulSequence;
AttrsImpl = (ParameterAttributes)pdwAttr;
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataPropertyInfo.cs
===================================================================
@@ -7,6 +7,7 @@
using Microsoft.Samples.Debugging.CorDebug;
using Microsoft.Samples.Debugging.CorMetadata.NativeApi;
using Microsoft.Samples.Debugging.CorDebug.NativeApi;
+using Microsoft.Samples.Debugging.Extensions;
namespace Microsoft.Samples.Debugging.CorMetadata
{
@@ -82,7 +83,7 @@ internal MetadataPropertyInfo (IMetadataImport importer, int propertyToken, Meta
m_propAttributes = (PropertyAttributes) pdwPropFlags;
m_name = szProperty.ToString ();
- MetadataHelperFunctions.GetCustomAttribute (importer, propertyToken, typeof (System.Diagnostics.DebuggerBrowsableAttribute));
+ MetadataHelperFunctionsExtensions.GetCustomAttribute (importer, propertyToken, typeof (System.Diagnostics.DebuggerBrowsableAttribute));
if (!m_importer.IsValidToken ((uint)m_pmdGetter))
m_pmdGetter = 0;
@@ -183,7 +184,7 @@ public override object[] GetCustomAttributes (Type attributeType, bool inherit)
public override object[] GetCustomAttributes (bool inherit)
{
if (m_customAttributes == null)
- m_customAttributes = MetadataHelperFunctions.GetDebugAttributes (m_importer, m_propertyToken);
+ m_customAttributes = MetadataHelperFunctionsExtensions.GetDebugAttributes (m_importer, m_propertyToken);
return m_customAttributes;
}
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataType.cs
===================================================================
@@ -15,12 +15,12 @@
using Microsoft.Samples.Debugging.CorDebug;
using Microsoft.Samples.Debugging.CorMetadata.NativeApi;
using Microsoft.Samples.Debugging.CorDebug.NativeApi;
+using Microsoft.Samples.Debugging.Extensions;
namespace Microsoft.Samples.Debugging.CorMetadata
{
public sealed class MetadataType : Type
{
- // [Xamarin] Expression evaluator.
internal MetadataType(IMetadataImport importer,int classToken)
{
Debug.Assert(importer!=null);
@@ -61,19 +61,21 @@ out ptkExtends
string baseTypeName = GetTypeName(importer, ptkExtends);
IntPtr ppvSig;
- if (baseTypeName == "System.Enum") {
- m_isEnum = true;
- m_enumUnderlyingType = GetEnumUnderlyingType (importer, classToken);
-
- // Check for flags enum by looking for FlagsAttribute
- uint sigSize = 0;
- ppvSig = IntPtr.Zero;
- int hr = importer.GetCustomAttributeByName (classToken, "System.FlagsAttribute", out ppvSig, out sigSize);
- if (hr < 0) {
- throw new COMException ("Exception looking for flags attribute", hr);
- }
- m_isFlagsEnum = (hr == 0); // S_OK means the attribute is present.
- }
+ if (baseTypeName == "System.Enum")
+ {
+ m_isEnum = true;
+ m_enumUnderlyingType = GetEnumUnderlyingType(importer,classToken);
+
+ // Check for flags enum by looking for FlagsAttribute
+ uint sigSize = 0;
+ ppvSig = IntPtr.Zero;
+ int hr = importer.GetCustomAttributeByName(classToken,"System.FlagsAttribute",out ppvSig,out sigSize);
+ if (hr < 0)
+ {
+ throw new COMException("Exception looking for flags attribute",hr);
+ }
+ m_isFlagsEnum = (hr == 0); // S_OK means the attribute is present.
+ }
}
}
@@ -337,7 +339,7 @@ public override object[] GetCustomAttributes(Type attributeType, bool inherit)
public override object[] GetCustomAttributes(bool inherit)
{
if (m_customAttributes == null)
- m_customAttributes = MetadataHelperFunctions.GetDebugAttributes (m_importer, m_typeToken);
+ m_customAttributes = MetadataHelperFunctionsExtensions.GetDebugAttributes (m_importer, m_typeToken);
return m_customAttributes;
}
@@ -411,17 +413,17 @@ public override Type GetNestedType(String name, BindingFlags bindingAttr)
// [Xamarin] Expression evaluator.
public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
{
- ArrayList al = new ArrayList ();
- IntPtr hEnum = new IntPtr ();
+ var al = new ArrayList ();
+ var hEnum = new IntPtr ();
int methodToken;
try {
while (true) {
uint size;
- ((IMetadataImport2)m_importer).EnumProperties (ref hEnum, (int) m_typeToken, out methodToken, 1, out size);
+ m_importer.EnumProperties (ref hEnum, (int) m_typeToken, out methodToken, 1, out size);
if (size == 0)
break;
- MetadataPropertyInfo prop = new MetadataPropertyInfo (m_importer, methodToken, this);
+ var prop = new MetadataPropertyInfo (m_importer, methodToken, this);
try {
MethodInfo mi = prop.GetGetMethod () ?? prop.GetSetMethod ();
if (mi == null)
@@ -472,21 +474,6 @@ public override FieldInfo GetField(String name, BindingFlags bindingAttr)
throw new NotImplementedException();
}
- // [Xamarin] Expression evaluator.
- bool FlagsMatch (bool ispublic, bool isstatic, BindingFlags flags)
- {
- if (ispublic && (flags & BindingFlags.Public) == 0)
- return false;
- if (!ispublic && (flags & BindingFlags.NonPublic) == 0)
- return false;
- if (isstatic && (flags & BindingFlags.Static) == 0)
- return false;
- if (!isstatic && (flags & BindingFlags.Instance) == 0)
- return false;
- return true;
- }
-
- // [Xamarin] Expression evaluator.
public override FieldInfo[] GetFields(BindingFlags bindingAttr)
{
ArrayList al = new ArrayList();
@@ -498,12 +485,13 @@ public override FieldInfo[] GetFields(BindingFlags bindingAttr)
while(true)
{
uint size;
- // TODO: Check this. Was just m_importer.EnumFields.
- ((IMetadataImport2) m_importer).EnumFields(ref hEnum,(int)m_typeToken,out fieldToken,1,out size);
+ m_importer.EnumFields(ref hEnum,(int)m_typeToken,out fieldToken,1,out size);
if(size==0)
break;
- MetadataFieldInfo field = new MetadataFieldInfo (m_importer, fieldToken, this);
- if (FlagsMatch (field.IsPublic, field.IsStatic, bindingAttr))
+ al.Add(new MetadataFieldInfo(m_importer,fieldToken,this));
+ // [Xamarin] Expression evaluator.
+ var field = new MetadataFieldInfo (m_importer, fieldToken, this);
+ if (MetadataExtensions.TypeFlagsMatch (field.IsPublic, field.IsStatic, bindingAttr))
al.Add (field);
}
}
@@ -514,7 +502,6 @@ public override FieldInfo[] GetFields(BindingFlags bindingAttr)
return (FieldInfo[]) al.ToArray(typeof(FieldInfo));
}
- // [Xamarin] Expression evaluator.
public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
{
ArrayList al = new ArrayList();
@@ -529,8 +516,9 @@ public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
m_importer.EnumMethods(ref hEnum,(int)m_typeToken,out methodToken,1,out size);
if(size==0)
break;
- MetadataMethodInfo met = new MetadataMethodInfo (m_importer, methodToken);
- if (FlagsMatch (met.IsPublic, met.IsStatic, bindingAttr))
+ // [Xamarin] Expression evaluator.
+ var met = new MetadataMethodInfo (m_importer, methodToken);
+ if (MetadataExtensions.TypeFlagsMatch (met.IsPublic, met.IsStatic, bindingAttr))
al.Add (met);
}
}
@@ -632,7 +620,6 @@ public CorElementType EnumUnderlyingType
}
}
- // [Xamarin] Expression evaluator.
// returns "" for normal classes, returns prefix for nested classes
private string GetNestedClassPrefix(IMetadataImport importer, int classToken, TypeAttributes attribs)
{
@@ -641,86 +628,32 @@ private string GetNestedClassPrefix(IMetadataImport importer, int classToken, Ty
// it is a nested class
int enclosingClass;
importer.GetNestedClassProps(classToken, out enclosingClass);
+ // [Xamarin] Expression evaluator.
m_declaringType = new MetadataType (importer, enclosingClass);
return m_declaringType.FullName + "+";
+ //MetadataType mt = new MetadataType(importer,enclosingClass);
+ //return mt.Name+".";
}
else
return String.Empty;
}
+ // member variables
+ private string m_name;
+ private IMetadataImport m_importer;
+ private int m_typeToken;
+ private bool m_isEnum;
+ private bool m_isFlagsEnum;
+ private CorElementType m_enumUnderlyingType;
+ private List<KeyValuePair<string,ulong>> m_enumValues;
// [Xamarin] Expression evaluator.
- internal static Type MakeDelegate (Type retType, List<Type> argTypes)
- {
-
- throw new NotImplementedException ();
- }
-
- // [Xamarin] Expression evaluator.
- public static Type MakeArray (Type t, List<int> sizes, List<int> loBounds)
- {
- MetadataType mt = t as MetadataType;
- if (mt != null) {
- if (sizes == null) {
- sizes = new List<int> ();
- sizes.Add (1);
- }
- mt.m_arraySizes = sizes;
- mt.m_arrayLoBounds = loBounds;
- return mt;
- }
- if (sizes == null || sizes.Count == 1)
- return t.MakeArrayType ();
- else
- return t.MakeArrayType (sizes.Capacity);
- }
-
- // [Xamarin] Expression evaluator.
- public static Type MakeByRef (Type t)
- {
- MetadataType mt = t as MetadataType;
- if (mt != null) {
- mt.m_isByRef = true;
- return mt;
- }
- return t.MakeByRefType ();
- }
-
- // [Xamarin] Expression evaluator.
- public static Type MakePointer (Type t)
- {
- MetadataType mt = t as MetadataType;
- if (mt != null) {
- mt.m_isPtr = true;
- return mt;
- }
- return t.MakeByRefType ();
- }
-
- // [Xamarin] Expression evaluator.
- public static Type MakeGeneric (Type t, List<Type> typeArgs)
- {
- MetadataType mt = (MetadataType)t;
- mt.m_typeArgs = typeArgs;
- return mt;
- }
-
- // member variables
- private string m_name;
- private IMetadataImport m_importer;
- private int m_typeToken;
- private bool m_isEnum;
- private bool m_isFlagsEnum;
- private CorElementType m_enumUnderlyingType;
- // [Xamarin] Expression evaluator.
- private List<KeyValuePair<string, ulong>> m_enumValues;
private object[] m_customAttributes;
private Type m_declaringType;
- private List<int> m_arraySizes;
- private List<int> m_arrayLoBounds;
- private bool m_isByRef, m_isPtr;
- private List<Type> m_typeArgs;
-
- }
+ internal List<int> m_arraySizes;
+ internal List<int> m_arrayLoBounds;
+ internal bool m_isByRef, m_isPtr;
+ internal List<Type> m_typeArgs;
+ }
// Sorts KeyValuePair<string,ulong>'s in increasing order by the value
class AscendingValueComparer<K, V> : IComparer<KeyValuePair<K,V>> where V:IComparable
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/debug/Debugger.cs
===================================================================
@@ -5,11 +5,8 @@
//---------------------------------------------------------------------
using System;
using System.Collections;
-using System.Collections.Generic;
using System.Diagnostics;
-#if !MDBG_FAKE_COM
using System.Runtime.InteropServices;
-#endif
using System.Runtime.InteropServices.ComTypes;
using System.Threading;
using System.Text;
@@ -18,6 +15,8 @@
using Microsoft.Samples.Debugging.CorDebug.NativeApi;
+using Microsoft.Samples.Debugging.Extensions;
+using System.Collections.Generic;
using Microsoft.Win32.SafeHandles;
@@ -31,8 +30,6 @@ namespace Microsoft.Samples.Debugging.CorDebug
public sealed class CorDebugger : MarshalByRefObject
{
private const int MaxVersionStringLength = 256; // == MAX_PATH
- // [Xamarin] Output redirection.
- public const int CREATE_REDIRECT_STD = 0x40000000;
public static string GetDebuggerVersionFromFile(string pathToExe)
{
@@ -153,7 +150,6 @@ String commandLine
return CreateProcess (applicationName, commandLine, ".");
}
- // [Xamarin] ASP.NET Debugging.
/**
* Launch a process under the control of the debugger.
*
@@ -164,16 +160,17 @@ String commandLine
String commandLine,
String currentDirectory
)
- {
+ {
+ // [Xamarin] ASP.NET Debugging.
return CreateProcess (applicationName, commandLine, currentDirectory, null, 0);
}
- // [Xamarin] ASP.NET Debugging.
/**
* Launch a process under the control of the debugger.
*
* Parameters are the same as the Win32 CreateProcess call.
*/
+ // [Xamarin] ASP.NET Debugging.
public CorProcess CreateProcess (
String applicationName,
String commandLine,
@@ -184,7 +181,6 @@ String currentDirectory
return CreateProcess (applicationName, commandLine, currentDirectory, environment, 0);
}
- // [Xamarin] ASP.NET Debugging and output redirection.
/**
* Launch a process under the control of the debugger.
*
@@ -204,26 +200,10 @@ int flags
si.cb = Marshal.SizeOf(si);
// initialize safe handles
+ // [Xamarin] ASP.NET Debugging and output redirection.
SafeFileHandle outReadPipe = null, errorReadPipe = null;
- if ((flags & CREATE_REDIRECT_STD) != 0) {
- CreateHandles (si, out outReadPipe, out errorReadPipe);
- flags &= ~CREATE_REDIRECT_STD;
- }
- else {
- si.hStdInput = new SafeFileHandle (IntPtr.Zero, false);
- si.hStdOutput = new SafeFileHandle (IntPtr.Zero, false);
- si.hStdError = new SafeFileHandle (IntPtr.Zero, false);
- }
-
- IntPtr env = IntPtr.Zero;
- if (environment != null) {
- string senv = null;
- foreach (KeyValuePair<string, string> var in environment) {
- senv += var.Key + "=" + var.Value + "\0";
- }
- senv += "\0";
- env = Marshal.StringToHGlobalAnsi (senv);
- }
+ DebuggerExtensions.SetupOutputRedirection (si, ref flags, outReadPipe, errorReadPipe);
+ IntPtr env = DebuggerExtensions.SetupEnvironment (environment);
CorProcess ret;
@@ -250,64 +230,12 @@ int flags
NativeMethods.CloseHandle (pi.hThread);
}
- if (env != IntPtr.Zero)
- Marshal.FreeHGlobal (env);
-
- if (outReadPipe != null) {
-
- // Close pipe handles (do not continue to modify the parent).
- // You need to make sure that no handles to the write end of the
- // output pipe are maintained in this process or else the pipe will
- // not close when the child process exits and the ReadFile will hang.
-
- si.hStdInput.Close ();
- si.hStdOutput.Close ();
- si.hStdError.Close ();
-
- ret.TrackStdOutput (outReadPipe, errorReadPipe);
- }
+ DebuggerExtensions.TearDownEnvironment (env);
+ DebuggerExtensions.TearDownOutputRedirection (outReadPipe, errorReadPipe, si, ret);
- return ret;
+ return ret;
}
- // [Xamarin] Output redirection.
- void CreateHandles (STARTUPINFO si, out SafeFileHandle outReadPipe, out SafeFileHandle errorReadPipe)
- {
- si.dwFlags |= 0x00000100; /*STARTF_USESTDHANDLES*/
- SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES ();
- sa.bInheritHandle = true;
- IntPtr curProc = NativeMethods.GetCurrentProcess ();
-
- SafeFileHandle outWritePipe, outReadPipeTmp;
- if (!NativeMethods.CreatePipe (out outReadPipeTmp, out outWritePipe, sa, 0))
- throw new Exception ("Pipe creation failed");
-
- // Create the child error pipe.
- SafeFileHandle errorWritePipe, errorReadPipeTmp;
- if (!NativeMethods.CreatePipe (out errorReadPipeTmp, out errorWritePipe, sa, 0))
- throw new Exception ("Pipe creation failed");
-
- // Create new output read and error read handles. Set
- // the Properties to FALSE. Otherwise, the child inherits the
- // properties and, as a result, non-closeable handles to the pipes
- // are created.
- if (!NativeMethods.DuplicateHandle (curProc, outReadPipeTmp, curProc, out outReadPipe, 0, false, NativeMethods.DUPLICATE_SAME_ACCESS))
- throw new Exception ("Pipe creation failed");
- if (!NativeMethods.DuplicateHandle (curProc, errorReadPipeTmp, curProc, out errorReadPipe, 0, false, NativeMethods.DUPLICATE_SAME_ACCESS))
- throw new Exception ("Pipe creation failed");
-
- NativeMethods.CloseHandle (curProc);
-
- // Close inheritable copies of the handles you do not want to be
- // inherited.
- outReadPipeTmp.Close ();
- errorReadPipeTmp.Close ();
-
- si.hStdInput = NativeMethods.GetStdHandle (NativeMethods.STD_INPUT_HANDLE);
- si.hStdOutput = outWritePipe;
- si.hStdError = errorWritePipe;
- }
-
/**
* Launch a process under the control of the debugger.
*
@@ -416,7 +344,6 @@ public void CanLaunchOrAttach(int processId, bool win32DebuggingEnabled)
//
////////////////////////////////////////////////////////////////////////////////
- // [Xamarin] .NET 4 API Version.
// called by constructors during initialization
private void InitFromVersion(string debuggerVersion)
{
@@ -427,6 +354,7 @@ private void InitFromVersion(string debuggerVersion)
}
ICorDebug rawDebuggingAPI;
+ // [Xamarin] .NET 4 API Version.
#if MDBG_FAKE_COM
// TODO: Ideally, there wouldn't be any difference in the corapi code for MDBG_FAKE_COM.
// This would require puting this initialization logic into the wrapper and interop assembly, which doesn't seem right.
@@ -610,60 +538,7 @@ public enum ProcessAccessOptions : int
ref Guid riid, // must be "ref NativeMethods.IIDICorDebug"
[MarshalAs(UnmanagedType.Interface)]out ICorDebug debuggingInterface
);
-
- // [Xamarin] Output redirection.
- [
- DllImport (Kernel32LibraryName, CharSet = CharSet.Auto, SetLastError = true)
- ]
- public static extern bool CreatePipe (out SafeFileHandle hReadPipe, out SafeFileHandle hWritePipe, SECURITY_ATTRIBUTES lpPipeAttributes, int nSize);
-
- // [Xamarin] Output redirection.
- [
- DllImport (Kernel32LibraryName)
- ]
- public static extern bool DuplicateHandle (
- IntPtr hSourceProcessHandle,
- SafeFileHandle hSourceHandle,
- IntPtr hTargetProcessHandle,
- out SafeFileHandle lpTargetHandle,
- uint dwDesiredAccess,
- bool bInheritHandle,
- uint dwOptions
- );
-
- // [Xamarin] Output redirection.
- public static uint DUPLICATE_CLOSE_SOURCE = 0x00000001;
- public static uint DUPLICATE_SAME_ACCESS = 0x00000002;
-
- // [Xamarin] Output redirection.
- [
- DllImport (Kernel32LibraryName)
- ]
- public static extern SafeFileHandle GetStdHandle (uint nStdHandle);
-
- // [Xamarin] Output redirection.
- public const uint STD_INPUT_HANDLE = unchecked ((uint)-10);
- public const uint STD_OUTPUT_HANDLE = unchecked ((uint)-11);
- public const uint STD_ERROR_HANDLE = unchecked ((uint)-12);
-
- // [Xamarin] Output redirection.
- [
- DllImport (Kernel32LibraryName)
- ]
- public static extern bool ReadFile (
- SafeFileHandle hFile,
- byte[] lpBuffer,
- int nNumberOfBytesToRead,
- out int lpNumberOfBytesRead,
- IntPtr lpOverlapped
- );
-
- // [Xamarin] Output redirection.
- [
- DllImport (Kernel32LibraryName, CharSet = CharSet.Auto, SetLastError = true)
- ]
- public static extern IntPtr GetCurrentProcess ();
- }
+ }
////////////////////////////////////////////////////////////////////////////////
//
@@ -1969,22 +1844,6 @@ internal enum ManagedCallbackTypeCount
Last = ManagedCallbackType.OnExceptionInCallback,
}
- // [Xamarin] Output redirection.
- public class CorTargetOutputEventArgs: EventArgs
- {
- public CorTargetOutputEventArgs (string text, bool isStdError)
- {
- Text = text;
- }
-
- public string Text { get; set; }
-
- public bool IsStdError { get; set; }
- }
-
- // [Xamarin] Output redirection.
- public delegate void CorTargetOutputEventHandler (Object sender, CorTargetOutputEventArgs e);
-
// Helper class to convert from COM-classic callback interface into managed args.
// Derived classes can overide the HandleEvent method to define the handling.
abstract public class ManagedCallbackBase : ICorDebugManagedCallback, ICorDebugManagedCallback2
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/debug/Process.cs
===================================================================
@@ -276,45 +276,6 @@ public override void Continue (bool outOfBand)
else
base.Continue(outOfBand);
}
-
- // [Xamarin] Output redirection.
- internal void TrackStdOutput (Microsoft.Win32.SafeHandles.SafeFileHandle outputPipe, Microsoft.Win32.SafeHandles.SafeFileHandle errorPipe)
- {
- Thread outputReader = new Thread (delegate ()
- {
- ReadOutput (outputPipe, false);
- });
- outputReader.Name = "Debugger output reader";
- outputReader.IsBackground = true;
- outputReader.Start ();
-
- Thread errorReader = new Thread (delegate ()
- {
- ReadOutput (errorPipe, true);
- });
- errorReader.Name = "Debugger error reader";
- errorReader.IsBackground = true;
- errorReader.Start ();
- }
-
- // [Xamarin] Output redirection.
- void ReadOutput (Microsoft.Win32.SafeHandles.SafeFileHandle pipe, bool isStdError)
- {
- byte[] buffer = new byte[256];
- int nBytesRead;
-
- try {
- while (true) {
- if (!NativeMethods.ReadFile (pipe, buffer, buffer.Length, out nBytesRead, IntPtr.Zero) || nBytesRead == 0)
- break; // pipe done - normal exit path.
- string s = System.Text.Encoding.Default.GetString (buffer, 0, nBytesRead);
- if (OnStdOutput != null)
- OnStdOutput (this, new CorTargetOutputEventArgs (s, isStdError));
- }
- }
- catch {
- }
- }
// when process is first created wait till callbacks are enabled.
private ManualResetEvent m_callbackAttachedEvent = new ManualResetEvent(false);
@@ -789,8 +750,5 @@ internal void DispatchEvent(ManagedCallbackType callback,CorEventArgs e)
}
}
- // [Xamarin] Output redirection.
- public event CorTargetOutputEventHandler OnStdOutput;
-
} /* class Process */
} /* namespace */
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/debug/Type.cs
===================================================================
@@ -91,7 +91,7 @@ public CorValue GetStaticFieldValue(int fieldToken, CorFrame frame)
// [Xamarin] Expression evaluator.
// Expose IEnumerable, which can be used with for-each constructs.
// This will provide an collection of CorType parameters.
- public CorType[] TypeParameters
+ public CorType[] TypeParameters
{
get
{
@@ -102,6 +102,7 @@ public CorType[] TypeParameters
foreach (CorType t in new CorTypeEnumerator (etp))
list.Add (t);
return list.ToArray ();
+ //return new CorTypeEnumerator (etp);
}
}
} /* class Type */
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/debug/Value.cs
===================================================================
@@ -739,9 +739,9 @@ public int[] GetDimensions()
{
Debug.Assert(Rank!=0);
uint[] dims = new uint[Rank];
- m_arrayVal.GetDimensions((uint)dims.Length, dims);
+ m_arrayVal.GetDimensions((uint)dims.Length,dims);
- int[] sdims = Array.ConvertAll<uint,int>(dims, delegate(uint u) { return (int)u; });
+ int[] sdims = Array.ConvertAll<uint,int>( dims, delegate(uint u) { return (int)u; } );
return sdims;
}
Modified: main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorDebuggerSession.cs
===================================================================
@@ -10,6 +10,7 @@
using Microsoft.Samples.Debugging.CorDebug.NativeApi;
using Microsoft.Samples.Debugging.CorMetadata;
using Microsoft.Samples.Debugging.CorSymbolStore;
+using Microsoft.Samples.Debugging.Extensions;
using Mono.Debugging.Backend;
using Mono.Debugging.Client;
using Mono.Debugging.Evaluation;
@@ -143,7 +144,7 @@ protected override void OnRun (DebuggerStartInfo startInfo)
int flags = 0;
if (!startInfo.UseExternalConsole) {
flags = (int)CreationFlags.CREATE_NO_WINDOW;
- flags |= CorDebugger.CREATE_REDIRECT_STD;
+ flags |= DebuggerExtensions.CREATE_REDIRECT_STD;
}
process = dbg.CreateProcess (startInfo.Command, cmdLine, startInfo.WorkingDirectory, env, flags);
@@ -167,9 +168,10 @@ protected override void OnRun (DebuggerStartInfo startInfo)
process.OnEvalComplete += new EvalEventHandler (OnEvalComplete);
process.OnEvalException += new EvalEventHandler (OnEvalException);
process.OnLogMessage += new LogMessageEventHandler (OnLogMessage);
- process.OnStdOutput += new CorTargetOutputEventHandler (OnStdOutput);
process.OnException2 += new CorException2EventHandler (OnException2);
+ process.RegisterStdOutput (OnStdOutput);
+
process.Continue (false);
});
OnStarted ();
@@ -1263,7 +1265,7 @@ public static IEnumerable<SequencePoint> GetSequencePoints (this ISymbolMethod m
public static Type GetTypeInfo (this CorType type, CorDebuggerSession session)
{
Type t;
- if (CorMetadataImport.CoreTypes.TryGetValue (type.Type, out t))
+ if (MetadataHelperFunctionsExtensions.CoreTypes.TryGetValue (type.Type, out t))
return t;
if (type.Type == CorElementType.ELEMENT_TYPE_ARRAY || type.Type == CorElementType.ELEMENT_TYPE_SZARRAY) {
@@ -1273,14 +1275,14 @@ public static Type GetTypeInfo (this CorType type, CorDebuggerSession session)
sizes.Add (1);
loBounds.Add (0);
}
- return MetadataType.MakeArray (type.FirstTypeParameter.GetTypeInfo (session), sizes, loBounds);
+ return MetadataExtensions.MakeArray (type.FirstTypeParameter.GetTypeInfo (session), sizes, loBounds);
}
if (type.Type == CorElementType.ELEMENT_TYPE_BYREF)
- return MetadataType.MakeByRef (type.FirstTypeParameter.GetTypeInfo (session));
+ return MetadataExtensions.MakeByRef (type.FirstTypeParameter.GetTypeInfo (session));
if (type.Type == CorElementType.ELEMENT_TYPE_PTR)
- return MetadataType.MakePointer (type.FirstTypeParameter.GetTypeInfo (session));
+ return MetadataExtensions.MakePointer (type.FirstTypeParameter.GetTypeInfo (session));
CorMetadataImport mi = session.GetMetadataForModule (type.Class.Module.Name);
if (mi != null) {
@@ -1290,7 +1292,7 @@ public static Type GetTypeInfo (this CorType type, CorDebuggerSession session)
List<Type> types = new List<Type> ();
foreach (CorType ct in targs)
types.Add (ct.GetTypeInfo (session));
- return MetadataType.MakeGeneric (t, types);
+ return MetadataExtensions.MakeGeneric (t, types);
}
else
return t;
Modified: main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorObjectAdaptor.cs
===================================================================
@@ -42,6 +42,7 @@
using CorDebugHandleType = Microsoft.Samples.Debugging.CorDebug.NativeApi.CorDebugHandleType;
using CorDebugMappingResult = Microsoft.Samples.Debugging.CorDebug.NativeApi.CorDebugMappingResult;
using CorElementType = Microsoft.Samples.Debugging.CorDebug.NativeApi.CorElementType;
+using Microsoft.Samples.Debugging.Extensions;
namespace MonoDevelop.Debugger.Win32
{
@@ -101,7 +102,7 @@ public override string GetTypeName (EvaluationContext ctx, object gtype)
CorType type = (CorType) gtype;
CorEvaluationContext cctx = (CorEvaluationContext) ctx;
Type t;
- if (CorMetadataImport.CoreTypes.TryGetValue (type.Type, out t))
+ if (MetadataHelperFunctionsExtensions.CoreTypes.TryGetValue (type.Type, out t))
return t.FullName;
try {
if (type.Type == CorElementType.ELEMENT_TYPE_ARRAY || type.Type == CorElementType.ELEMENT_TYPE_SZARRAY)
@@ -517,7 +518,7 @@ bool IsAssignableFrom (CorEvaluationContext ctx, Type baseType, CorType ctype)
if (tname == ctypeName)
return true;
- if (CorMetadataImport.CoreTypes.ContainsKey (ctype.Type))
+ if (MetadataHelperFunctionsExtensions.CoreTypes.ContainsKey (ctype.Type))
return false;
switch (ctype.Type) {
@@ -623,7 +624,7 @@ public override object CreateValue (EvaluationContext gctx, object value)
});
}
- foreach (KeyValuePair<CorElementType, Type> tt in CorMetadataImport.CoreTypes) {
+ foreach (KeyValuePair<CorElementType, Type> tt in MetadataHelperFunctionsExtensions.CoreTypes) {
if (tt.Value == value.GetType ()) {
CorValue val = ctx.Eval.CreateValue (tt.Key, null);
CorGenericValue gv = val.CastToGenericValue ();
@@ -736,7 +737,7 @@ public static CorValue GetRealObject (EvaluationContext ctx, CorValue obj)
if (obj.ExactType.Type == CorElementType.ELEMENT_TYPE_STRING)
return obj.CastToStringValue ();
- if (CorMetadataImport.CoreTypes.ContainsKey (obj.Type)) {
+ if (MetadataHelperFunctionsExtensions.CoreTypes.ContainsKey (obj.Type)) {
CorGenericValue genVal = obj.CastToGenericValue ();
if (genVal != null)
return genVal;
Commit: 57b3d13bdf94c49918280bff6b22106eed1c214e
Author: Therzok <[email protected]> (Therzok)
Date: 2013-11-05 18:51:46 GMT
URL: https://github.com/mono/monodevelop/commit/57b3d13bdf94c49918280bff6b22106eed1c214e
[CorDebug] Fix Call Stack tree.
Changed paths:
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Extensions/MetadataExtensions.cs
M main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorDebuggerBacktrace.cs
M main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorDebuggerSession.cs
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Extensions/MetadataExtensions.cs
===================================================================
@@ -267,6 +267,9 @@ static internal object[] GetDebugAttributes (IMetadataImport importer, int token
attr = GetCustomAttribute (importer, token, typeof (System.Runtime.CompilerServices.CompilerGeneratedAttribute));
if (attr != null)
attributes.Add (attr);
+ attr = GetCustomAttribute (importer, token, typeof (System.Diagnostics.DebuggerHiddenAttribute));
+ if (attr != null)
+ attributes.Add (attr);
return attributes.Count == 0 ? emptyAttributes : attributes.ToArray ();
}
Modified: main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorDebuggerBacktrace.cs
===================================================================
@@ -78,13 +78,21 @@ public override StackFrame[] GetStackFrames (int firstIndex, int lastIndex)
internal static StackFrame CreateFrame (CorDebuggerSession session, CorFrame frame)
{
+ // TODO: Fix remaining.
uint address = 0;
+ //string typeFQN;
+ //string typeFullName;
+ string addressSpace = "";
string file = "";
int line = 0;
+ int column = 0;
string method = "";
string lang = "";
string module = "";
string type = "";
+ bool hasDebugInfo = false;
+ bool hidden = false;
+ bool external = true;
if (frame.FrameType == CorFrameType.ILFrame) {
if (frame.Function != null) {
@@ -93,27 +101,30 @@ internal static StackFrame CreateFrame (CorDebuggerSession session, CorFrame fra
MethodInfo mi = importer.GetMethodInfo (frame.Function.Token);
method = mi.DeclaringType.FullName + "." + mi.Name;
type = mi.DeclaringType.FullName;
+ addressSpace = mi.Name;
ISymbolReader reader = session.GetReaderForModule (frame.Function.Module.Name);
if (reader != null) {
ISymbolMethod met = reader.GetMethod (new SymbolToken (frame.Function.Token));
if (met != null) {
- uint offset;
CorDebugMappingResult mappingResult;
- frame.GetIP (out offset, out mappingResult);
+ frame.GetIP (out address, out mappingResult);
SequencePoint prevSp = null;
foreach (SequencePoint sp in met.GetSequencePoints ()) {
- if (sp.Offset > offset)
+ if (sp.Offset > address)
break;
prevSp = sp;
}
if (prevSp != null) {
line = prevSp.Line;
+ column = prevSp.Offset;
file = prevSp.Document.URL;
+ address = (uint)prevSp.Offset;
}
}
}
}
lang = "Managed";
+ hasDebugInfo = true;
}
else if (frame.FrameType == CorFrameType.NativeFrame) {
frame.GetNativeIP (out address);
@@ -129,10 +140,16 @@ internal static StackFrame CreateFrame (CorDebuggerSession session, CorFrame fra
case CorDebugInternalFrameType.STUBFRAME_FUNC_EVAL: method = "[Function Evaluation]"; break;
}
}
+
+ // Implement custom attributes in CorMetadata.cs
+ // if (frame.Function.GetMethodInfo (session).GetCustomAttributes (System.Diagnostics.DebuggerHiddenAttribute, true) != null)
+ // hidden = true;
+
if (method == null)
method = "<Unknown>";
- var loc = new SourceLocation (method, file, line);
- return new StackFrame ((long) address, loc, lang);
+
+ var loc = new SourceLocation (method, file, line, column);
+ return new StackFrame ((long) address, addressSpace, loc, lang, external, hasDebugInfo, hidden, null, null);
}
#endregion
Modified: main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorDebuggerSession.cs
===================================================================
@@ -934,7 +934,7 @@ public CorValue RuntimeInvoke (CorEvaluationContext ctx, CorFunction function, C
mc.OnGetDescription = delegate {
MethodInfo met = function.GetMethodInfo (ctx.Session);
if (met != null)
- return met.Name;
+ return met.DeclaringType.FullName + "." + met.Name;
else
return "<Unknown>";
};
Commit: 0099255bee9f2c3f65000c8c8cd6a0657e4a9989
Author: Therzok <[email protected]> (Therzok)
Date: 2013-11-05 18:51:47 GMT
URL: https://github.com/mono/monodevelop/commit/0099255bee9f2c3f65000c8c8cd6a0657e4a9989
[CorDebug] Implemented Custom Attributes for methods and stub code for DebuggerHidden.
Changed paths:
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/CorMetadata.cs
M main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorDebuggerBacktrace.cs
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/CorMetadata.cs
===================================================================
@@ -373,20 +373,30 @@ public override MethodInfo GetBaseDefinition()
throw new NotImplementedException();
}
- public override bool IsDefined (Type attributeType, bool inherit)
- {
- throw new NotImplementedException();
- }
+ // [Xamarin] Expression evaluator.
+ public override bool IsDefined (Type attributeType, bool inherit)
+ {
+ return GetCustomAttributes (attributeType, inherit).Length > 0;
+ }
- public override object[] GetCustomAttributes(Type attributeType, bool inherit)
- {
- throw new NotImplementedException();
- }
+ // [Xamarin] Expression evaluator.
+ public override object[] GetCustomAttributes (Type attributeType, bool inherit)
+ {
+ ArrayList list = new ArrayList ();
+ foreach (object ob in GetCustomAttributes (inherit)) {
+ if (attributeType.IsInstanceOfType (ob))
+ list.Add (ob);
+ }
+ return list.ToArray ();
+ }
- public override object[] GetCustomAttributes(bool inherit)
- {
- throw new NotImplementedException();
- }
+ // [Xamarin] Expression evaluator.
+ public override object[] GetCustomAttributes(bool inherit)
+ {
+ if (m_customAttributes == null)
+ m_customAttributes = MetadataHelperFunctionsExtensions.GetDebugAttributes (m_importer, m_methodToken);
+ return m_customAttributes;
+ }
public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture)
{
@@ -449,6 +459,7 @@ public string[] GetGenericArgumentNames()
// [Xamarin] Expression evaluator.
private List<Type> m_argTypes;
private Type m_retType;
+ private object[] m_customAttributes;
}
public enum MetadataTokenType
Modified: main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorDebuggerBacktrace.cs
===================================================================
@@ -122,6 +122,8 @@ internal static StackFrame CreateFrame (CorDebuggerSession session, CorFrame fra
}
}
}
+ // FIXME: Still steps into.
+ //hidden = mi.GetCustomAttributes (true).Any (v => v is System.Diagnostics.DebuggerHiddenAttribute);
}
lang = "Managed";
hasDebugInfo = true;
@@ -141,10 +143,6 @@ internal static StackFrame CreateFrame (CorDebuggerSession session, CorFrame fra
}
}
- // Implement custom attributes in CorMetadata.cs
- // if (frame.Function.GetMethodInfo (session).GetCustomAttributes (System.Diagnostics.DebuggerHiddenAttribute, true) != null)
- // hidden = true;
-
if (method == null)
method = "<Unknown>";
Commit: 9488bc9ac610bd7db1fa2d9cbe133b6591b19f99
Author: Therzok <[email protected]> (Therzok)
Date: 2013-11-05 18:51:47 GMT
URL: https://github.com/mono/monodevelop/commit/9488bc9ac610bd7db1fa2d9cbe133b6591b19f99
[CorDebug] First attempt at fixing up evaluation.
Interfaces don't work yet. And class typing is screwed.
Changed paths:
M main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorObjectAdaptor.cs
M main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/FieldReference.cs
M main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/PropertyReference.cs
Modified: main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorObjectAdaptor.cs
===================================================================
@@ -43,6 +43,7 @@
using CorDebugMappingResult = Microsoft.Samples.Debugging.CorDebug.NativeApi.CorDebugMappingResult;
using CorElementType = Microsoft.Samples.Debugging.CorDebug.NativeApi.CorElementType;
using Microsoft.Samples.Debugging.Extensions;
+using System.Linq;
namespace MonoDevelop.Debugger.Win32
{
@@ -97,6 +98,11 @@ public override bool IsClass (EvaluationContext ctx, object type)
return ((CorType)type).Type == CorElementType.ELEMENT_TYPE_CLASS && ((CorType)type).Class != null;
}
+ public override bool IsGenericType (EvaluationContext ctx, object type)
+ {
+ return (((CorType)type).Type == CorElementType.ELEMENT_TYPE_GENERICINST) || base.IsGenericType (ctx, type);
+ }
+
public override string GetTypeName (EvaluationContext ctx, object gtype)
{
CorType type = (CorType) gtype;
@@ -117,8 +123,8 @@ public override string GetTypeName (EvaluationContext ctx, object gtype)
return type.GetTypeInfo (cctx.Session).FullName;
}
catch (Exception ex) {
- Console.WriteLine (ex);
- throw;
+ ctx.WriteDebuggerError (ex);
+ return t.FullName;
}
}
@@ -138,7 +144,7 @@ public override object[] GetTypeArgs (EvaluationContext ctx, object type)
return CastArray<object> (types);
}
- IEnumerable<Type> GetAllTypes (EvaluationContext gctx)
+ static IEnumerable<Type> GetAllTypes (EvaluationContext gctx)
{
CorEvaluationContext ctx = (CorEvaluationContext) gctx;
foreach (CorModule mod in ctx.Session.GetModules ()) {
@@ -184,14 +190,18 @@ public override string CallToString(EvaluationContext ctx, object objr)
if ((obj is CorReferenceValue) && ((CorReferenceValue)obj).IsNull)
return string.Empty;
- CorStringValue stringVal = obj as CorStringValue;
+ var stringVal = obj as CorStringValue;
if (stringVal != null)
return stringVal.String;
- CorArrayValue arr = obj as CorArrayValue;
+ var genericVal = obj as CorGenericValue;
+ if (genericVal != null)
+ return genericVal.GetValue ().ToString ();
+
+ var arr = obj as CorArrayValue;
if (arr != null)
{
- StringBuilder tn = new StringBuilder (GetDisplayTypeName (ctx, arr.ExactType.FirstTypeParameter));
+ var tn = new StringBuilder (GetDisplayTypeName (ctx, arr.ExactType.FirstTypeParameter));
tn.Append("[");
int[] dims = arr.GetDimensions();
for (int n = 0; n < dims.Length; n++)
@@ -204,8 +214,8 @@ public override string CallToString(EvaluationContext ctx, object objr)
return tn.ToString();
}
- CorEvaluationContext cctx = (CorEvaluationContext)ctx;
- CorObjectValue co = obj as CorObjectValue;
+ var cctx = (CorEvaluationContext)ctx;
+ var co = obj as CorObjectValue;
if (co != null)
{
if (IsEnum (ctx, co.ExactType))
@@ -243,13 +253,13 @@ public override string CallToString(EvaluationContext ctx, object objr)
return nval.ToString ();
}
- CorType targetType = (CorType)GetValueType (ctx, objr);
+ var targetType = (CorType)GetValueType (ctx, objr);
MethodInfo met = OverloadResolve (cctx, "ToString", targetType, new CorType[0], BindingFlags.Public | BindingFlags.Instance, false);
if (met != null && met.DeclaringType.FullName != "System.Object") {
- object[] args = new object[0];
+ var args = new object[0];
object ores = RuntimeInvoke (ctx, targetType, objr, "ToString", args, args);
- CorStringValue res = GetRealObject (ctx, ores) as CorStringValue;
+ var res = GetRealObject (ctx, ores) as CorStringValue;
if (res != null)
return res.String;
}
@@ -257,22 +267,16 @@ public override string CallToString(EvaluationContext ctx, object objr)
return GetDisplayTypeName (ctx, targetType);
}
- CorGenericValue genVal = obj as CorGenericValue;
- if (genVal != null)
- {
- return genVal.GetValue().ToString ();
- }
-
return base.CallToString(ctx, obj);
}
public override object CreateTypeObject (EvaluationContext ctx, object type)
{
- CorType t = (CorType)type;
+ var t = (CorType)type;
string tname = GetTypeName (ctx, t) + ", " + System.IO.Path.GetFileNameWithoutExtension (t.Class.Module.Assembly.Name);
- CorType stype = (CorType) GetType (ctx, "System.Type");
- object[] argTypes = new object[] { GetType (ctx, "System.String") };
- object[] argVals = new object[] { CreateValue (ctx, tname) };
+ var stype = (CorType) GetType (ctx, "System.Type");
+ object[] argTypes = { GetType (ctx, "System.String") };
+ object[] argVals = { CreateValue (ctx, tname) };
return RuntimeInvoke (ctx, stype, null, "GetType", argTypes, argVals);
}
@@ -336,6 +340,7 @@ public override object RuntimeInvoke (EvaluationContext gctx, object gtargetType
CorEvaluationContext ctx = (CorEvaluationContext)gctx;
MethodInfo method = OverloadResolve (ctx, methodName, targetType, argTypes, flags, true);
ParameterInfo[] parameters = method.GetParameters ();
+ // TODO: Check this.
for (int n = 0; n < parameters.Length; n++) {
if (parameters[n].ParameterType == typeof(object) && (IsValueType (ctx, argValues[n])))
argValues[n] = Box (ctx, argValues[n]);
@@ -375,9 +380,16 @@ MethodInfo OverloadResolve (CorEvaluationContext ctx, string methodName, CorType
candidates.Add (met);
}
}
+
+ if (argtypes == null && candidates.Count > 0)
+ break; // when argtypes is null, we are just looking for *any* match (not a specific match)
+
if (methodName == ".ctor")
break; // Can't create objects using constructor from base classes
- currentType = currentType.Base;
+ if (rtype.BaseType == null && rtype.FullName != "System.Object")
+ currentType = ctx.Adapter.GetType (ctx, "System.Object") as CorType;
+ else
+ currentType = currentType.Base;
}
return OverloadResolve (ctx, GetTypeName (ctx, type), methodName, argtypes, candidates, throwIfNotFound);
@@ -482,30 +494,32 @@ MethodInfo OverloadResolve (CorEvaluationContext ctx, string typeName, string me
public override string[] GetImportedNamespaces (EvaluationContext ctx)
{
- Set<string> list = new Set<string> ();
+ var list = new HashSet<string> ();
foreach (Type t in GetAllTypes (ctx)) {
list.Add (t.Namespace);
}
- string[] arr = new string[list.Count];
- list.CopyTo (arr, 0);
+ var arr = new string[list.Count];
+ list.CopyTo (arr);
return arr;
}
public override void GetNamespaceContents (EvaluationContext ctx, string namspace, out string[] childNamespaces, out string[] childTypes)
{
- Set<string> nss = new Set<string> ();
- List<string> types = new List<string> ();
+ var nss = new HashSet<string> ();
+ var types = new HashSet<string> ();
+ string namspacePrefix = namspace.Length > 0 ? namspace + "." : "";
foreach (Type t in GetAllTypes (ctx)) {
- if (t.Namespace == namspace)
+ if (t.Namespace == namspace || t.Namespace.StartsWith (namspacePrefix, StringComparison.InvariantCulture)) {
+ nss.Add (t.Namespace);
types.Add (t.FullName);
- else if (t.Namespace.StartsWith (namspace + ".", StringComparison.Ordinal)) {
- if (t.Namespace.IndexOf ('.', namspace.Length + 1) == -1)
- nss.Add (t.Namespace);
}
}
+
childNamespaces = new string[nss.Count];
- nss.CopyTo (childNamespaces, 0);
- childTypes = types.ToArray ();
+ nss.CopyTo (childNamespaces);
+
+ childTypes = new string [types.Count];
+ types.CopyTo (childTypes);
}
bool IsAssignableFrom (CorEvaluationContext ctx, Type baseType, CorType ctype)
@@ -539,7 +553,7 @@ bool IsAssignableFrom (CorEvaluationContext ctx, Type baseType, CorType ctype)
public override object TryCast (EvaluationContext ctx, object val, object type)
{
- CorType ctype = (CorType) GetValueType (ctx, val);
+ var ctype = (CorType) GetValueType (ctx, val);
CorValue obj = GetRealObject(ctx, val);
string tname = GetTypeName(ctx, type);
string ctypeName = GetValueTypeName (ctx, val);
@@ -555,26 +569,9 @@ public override object TryCast (EvaluationContext ctx, object val, object type)
if (obj is CorArrayValue)
return (ctypeName == tname || ctypeName == "System.Array") ? val : null;
- if (obj is CorObjectValue)
- {
- CorObjectValue co = (CorObjectValue)obj;
- if (IsEnum (ctx, co.ExactType)) {
- ValueReference rval = GetMember (ctx, null, val, "value__");
- return TryCast (ctx, rval.Value, type);
- }
-
- while (ctype != null)
- {
- if (GetTypeName(ctx, ctype) == tname)
- return val;
- ctype = ctype.Base;
- }
- return null;
- }
-
- CorGenericValue genVal = obj as CorGenericValue;
- if (genVal != null) {
- Type t = Type.GetType(tname);
+ var genVal = obj as CorGenericValue;
+ if (genVal != null) {
+ Type t = Type.GetType(tname);
try {
if (t != null && t.IsPrimitive && t != typeof (string)) {
object pval = genVal.GetValue ();
@@ -592,6 +589,23 @@ public override object TryCast (EvaluationContext ctx, object val, object type)
}
} catch {
}
+ }
+
+ if (obj is CorObjectValue)
+ {
+ var co = (CorObjectValue)obj;
+ if (IsEnum (ctx, co.ExactType)) {
+ ValueReference rval = GetMember (ctx, null, val, "value__");
+ return TryCast (ctx, rval.Value, type);
+ }
+
+ while (ctype != null)
+ {
+ if (GetTypeName(ctx, ctype) == tname)
+ return val;
+ ctype = ctype.Base;
+ }
+ return null;
}
return null;
}
@@ -632,7 +646,8 @@ public override object CreateValue (EvaluationContext gctx, object value)
return new CorValRef (val);
}
}
- throw new NotSupportedException ();
+ ctx.WriteDebuggerError (new NotSupportedException (String.Format ("Unable to create value for type: {0}", value.GetType ())));
+ return null;
}
public override object CreateValue (EvaluationContext ctx, object type, params object[] gargs)
@@ -831,7 +846,7 @@ public override ValueReference GetIndexerReference (EvaluationContext ctx, objec
catch {
// Ignore
}
- if (mi != null && mi.GetParameters ().Length > 0) {
+ if (mi != null && !mi.IsStatic && mi.GetParameters ().Length > 0) {
candidates.Add (mi);
props.Add (prop);
propTypes.Add (t);
@@ -842,6 +857,10 @@ public override ValueReference GetIndexerReference (EvaluationContext ctx, objec
MethodInfo idx = OverloadResolve (cctx, GetTypeName (ctx, targetType), null, types, candidates, true);
int i = candidates.IndexOf (idx);
+
+ if (props [i].GetGetMethod (true) == null)
+ return null;
+
return new PropertyReference (ctx, props[i], (CorValRef)target, propTypes[i], values);
}
@@ -875,14 +894,34 @@ public override bool HasMember (EvaluationContext ctx, object tt, string memberN
protected override IEnumerable<ValueReference> GetMembers (EvaluationContext ctx, object tt, object gval, BindingFlags bindingFlags)
{
- CorType t = (CorType) tt;
- CorValRef val = (CorValRef) gval;
+ var subProps = new Dictionary<string, PropertyInfo> ();
+ var t = (CorType) tt;
+ var val = (CorValRef) gval;
+ CorType realType = null;
+ if (gval != null && (bindingFlags & BindingFlags.Instance) != 0)
+ realType = GetValueType (ctx, gval) as CorType;
if (t.Class == null)
yield break;
CorEvaluationContext cctx = (CorEvaluationContext) ctx;
+ // First of all, get a list of properties overriden in sub-types
+ while (realType != null && realType != t) {
+ Type type = realType.GetTypeInfo (cctx.Session);
+ foreach (PropertyInfo prop in type.GetProperties (bindingFlags | BindingFlags.DeclaredOnly)) {
+ MethodInfo mi = prop.GetGetMethod (true);
+ if (mi == null || mi.GetParameters ().Length != 0 || mi.IsAbstract || !mi.IsVirtual || mi.IsStatic)
+ continue;
+ if (mi.IsPublic && ((bindingFlags & BindingFlags.Public) == 0))
+ continue;
+ if (!mi.IsPublic && ((bindingFlags & BindingFlags.NonPublic) == 0))
+ continue;
+ subProps [prop.Name] = prop;
+ }
+ realType = realType.Base;
+ }
+
while (t != null) {
Type type = t.GetTypeInfo (cctx.Session);
@@ -896,42 +935,121 @@ protected override IEnumerable<ValueReference> GetMembers (EvaluationContext ctx
} catch {
// Ignore
}
- if (mi != null && mi.GetParameters ().Length == 0)
+ if (mi == null || mi.GetParameters ().Length != 0 || mi.IsAbstract)
+ continue;
+
+ // If a property is overriden, return the override instead of the base property
+ PropertyInfo overridden;
+ if (mi.IsVirtual && subProps.TryGetValue (prop.Name, out overridden)) {
+ mi = overridden.GetGetMethod (true);
+ if (mi == null)
+ continue;
+
+ var declaringType = GetType (ctx, overridden.DeclaringType.FullName) as CorType;
+ yield return new PropertyReference (ctx, overridden, val, declaringType);
+ } else {
yield return new PropertyReference (ctx, prop, val, t);
+ }
}
if ((bindingFlags & BindingFlags.DeclaredOnly) != 0)
break;
t = t.Base;
}
}
-
- public static string UnscapeString (string text)
+
+ static bool IsIEnumerable (Type type)
{
- StringBuilder sb = new StringBuilder ();
- for (int i = 0; i < text.Length; i++) {
- char c = text[i];
- if (c != '\\') {
- sb.Append (c);
- continue;
+ if (!type.IsInterface)
+ return false;
+
+ if (type.Namespace == "System.Collections" && type.Name == "IEnumerable")
+ return true;
+
+ if (type.Namespace == "System.Collections.Generic" && type.Name == "IEnumerable`1")
+ return true;
+
+ return false;
+ }
+
+ static bool IsIEnumerable (CorType type, CorDebuggerSession session)
+ {
+ return IsIEnumerable (type.GetTypeInfo (session));
+ }
+
+ protected override CompletionData GetMemberCompletionData (EvaluationContext ctx, ValueReference vr)
+ {
+ var properties = new HashSet<string> ();
+ var methods = new HashSet<string> ();
+ var fields = new HashSet<string> ();
+ var data = new CompletionData ();
+ var type = vr.Type as CorType;
+ bool isEnumerable = false;
+ Type t;
+
+ var cctx = (CorEvaluationContext)ctx;
+ while (type != null) {
+ t = type.GetTypeInfo (cctx.Session);
+ if (!isEnumerable && IsIEnumerable (t))
+ isEnumerable = true;
+
+ foreach (var field in t.GetFields ()) {
+ if (field.IsStatic || field.IsSpecialName || !field.IsPublic)
+ continue;
+
+ if (fields.Add (field.Name))
+ data.Items.Add (new CompletionItem (field.Name, FieldReference.GetFlags (field)));
}
- i++;
- if (i >= text.Length)
- return null;
-
- switch (text[i]) {
- case '\\': c = '\\'; break;
- case 'a': c = '\a'; break;
- case 'b': c = '\b'; break;
- case 'f': c = '\f'; break;
- case 'v': c = '\v'; break;
- case 'n': c = '\n'; break;
- case 'r': c = '\r'; break;
- case 't': c = '\t'; break;
- default: return null;
+
+ foreach (var property in t.GetProperties ()) {
+ var getter = property.GetGetMethod (true);
+
+ if (getter == null || getter.IsStatic || !getter.IsPublic)
+ continue;
+
+ if (properties.Add (property.Name))
+ data.Items.Add (new CompletionItem (property.Name, PropertyReference.GetFlags (property)));
+ }
+
+ foreach (var method in t.GetMethods ()) {
+ if (method.IsStatic || method.IsConstructor || method.IsSpecialName || !method.IsPublic)
+ continue;
+
+ if (methods.Add (method.Name))
+ data.Items.Add (new CompletionItem (method.Name, ObjectValueFlags.Method | ObjectValueFlags.Public));
+ }
+
+ if (t.BaseType == null && t.FullName != "System.Object")
+ type = ctx.Adapter.GetType (ctx, "System.Object") as CorType;
+ else
+ type = type.Base;
+ }
+
+ t = type.GetTypeInfo (cctx.Session);
+ foreach (var iface in t.GetInterfaces ()) {
+ if (!isEnumerable && IsIEnumerable (iface)) {
+ isEnumerable = true;
+ break;
+ }
+ }
+
+ if (isEnumerable) {
+ // Look for LINQ extension methods...
+ var linq = ctx.Adapter.GetType (ctx, "System.Linq.Enumerable") as CorType;
+ if (linq != null) {
+ var linqt = linq.GetTypeInfo (cctx.Session);
+ foreach (var method in linqt.GetMethods ()) {
+ if (!method.IsStatic || method.IsConstructor || method.IsSpecialName || !method.IsPublic)
+ continue;
+
+ if (methods.Add (method.Name))
+ data.Items.Add (new CompletionItem (method.Name, ObjectValueFlags.Method | ObjectValueFlags.Public));
+ }
}
- sb.Append (c);
}
- return sb.ToString ();
+
+ data.ExpressionLength = 0;
+
+ return data;
}
public override object TargetObjectToObject (EvaluationContext ctx, object objr)
@@ -942,8 +1060,18 @@ public override object TargetObjectToObject (EvaluationContext ctx, object objr)
return new EvaluationResult ("(null)");
CorStringValue stringVal = obj as CorStringValue;
- if (stringVal != null)
- return stringVal.String;
+ if (stringVal != null) {
+ string str;
+ if (ctx.Options.EllipsizeStrings) {
+ str = stringVal.String;
+ if (str.Length > ctx.Options.EllipsizedLength)
+ str = str.Substring (0, ctx.Options.EllipsizedLength) + EvaluationOptions.Ellipsis;
+ } else {
+ str = stringVal.String;
+ }
+ return str;
+
+ }
CorArrayValue arr = obj as CorArrayValue;
if (arr != null)
@@ -1010,7 +1138,7 @@ protected override IEnumerable<ValueReference> OnGetParameters (EvaluationContex
int count = ctx.Frame.GetArgumentCount ();
for (int n = 0; n < count; n++) {
int locn = n;
- CorValRef vref = new CorValRef (delegate {
+ var vref = new CorValRef (delegate {
return ctx.Frame.GetArgument (locn);
});
yield return new VariableReference (ctx, vref, "arg_" + (n + 1), ObjectValueFlags.Parameter);
@@ -1145,7 +1273,8 @@ protected override TypeDisplayData OnGetTypeDisplayData (EvaluationContext ctx,
}
if (atts.Length > 0) {
hasTypeData = true;
- if (memberData == null) memberData = new Dictionary<string, DebuggerBrowsableState> ();
+ if (memberData == null)
+ memberData = new Dictionary<string, DebuggerBrowsableState> ();
memberData[m.Name] = ((DebuggerBrowsableAttribute)atts[0]).State;
}
}
@@ -1157,5 +1286,19 @@ protected override TypeDisplayData OnGetTypeDisplayData (EvaluationContext ctx,
else
return null;
}
+
+ // TODO: implement in metadatatype
+ public override IEnumerable<object> GetNestedTypes (EvaluationContext ctx, object type)
+ {
+ return base.GetNestedTypes (ctx, type);
+ }
+
+ // TODO: implement for session
+ public override bool IsExternalType (EvaluationContext ctx, object type)
+ {
+ return base.IsExternalType (ctx, type);
+ }
+
+ // TODO: Implement IsTypeLoaded, ForceTypeLoad
}
}
Modified: main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/FieldReference.cs
===================================================================
@@ -38,6 +38,7 @@ public class FieldReference: ValueReference
readonly FieldInfo field;
readonly CorValRef thisobj;
readonly CorValRef.ValueLoader loader;
+ readonly ObjectValueFlags flags;
public FieldReference (EvaluationContext ctx, CorValRef thisobj, CorType type, FieldInfo field)
: base (ctx)
@@ -48,6 +49,8 @@ public FieldReference (EvaluationContext ctx, CorValRef thisobj, CorType type, F
if (field.IsStatic)
this.thisobj = null;
+ flags = GetFlags (field);
+
loader = delegate {
return ((CorValRef)Value).Val;
};
@@ -114,27 +117,32 @@ public FieldReference (EvaluationContext ctx, CorValRef thisobj, CorType type, F
public override ObjectValueFlags Flags {
get {
- ObjectValueFlags flags = ObjectValueFlags.Field;
+ return flags;
+ }
+ }
- if (field.IsStatic)
- flags |= ObjectValueFlags.Global;
+ internal static ObjectValueFlags GetFlags (FieldInfo field)
+ {
+ ObjectValueFlags flags = ObjectValueFlags.Field;
- if (field.IsFamilyOrAssembly)
- flags |= ObjectValueFlags.InternalProtected;
- else if (field.IsFamilyAndAssembly)
- flags |= ObjectValueFlags.Internal;
- else if (field.IsFamily)
- flags |= ObjectValueFlags.Protected;
- else if (field.IsPublic)
- flags |= ObjectValueFlags.Public;
- else
- flags |= ObjectValueFlags.Private;
+ if (field.IsStatic)
+ flags |= ObjectValueFlags.Global;
- if (field.IsLiteral)
- flags |= ObjectValueFlags.ReadOnly;
+ if (field.IsFamilyOrAssembly)
+ flags |= ObjectValueFlags.InternalProtected;
+ else if (field.IsFamilyAndAssembly)
+ flags |= ObjectValueFlags.Internal;
+ else if (field.IsFamily)
+ flags |= ObjectValueFlags.Protected;
+ else if (field.IsPublic)
+ flags |= ObjectValueFlags.Public;
+ else
+ flags |= ObjectValueFlags.Private;
- return flags;
- }
+ if (field.IsLiteral)
+ flags |= ObjectValueFlags.ReadOnly;
+
+ return flags;
}
}
}
Modified: main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/PropertyReference.cs
===================================================================
@@ -40,6 +40,7 @@ class PropertyReference: ValueReference
readonly CorModule module;
readonly CorType declaringType;
readonly CorValRef.ValueLoader loader;
+ readonly ObjectValueFlags flags;
CorValRef cachedValue;
public PropertyReference (EvaluationContext ctx, PropertyInfo prop, CorValRef thisobj, CorType declaringType)
@@ -57,6 +58,8 @@ public PropertyReference (EvaluationContext ctx, PropertyInfo prop, CorValRef th
if (!prop.GetGetMethod (true).IsStatic)
this.thisobj = thisobj;
+ flags = GetFlags (prop);
+
loader = delegate {
return ((CorValRef)Value).Val;
};
@@ -134,31 +137,36 @@ public PropertyReference (EvaluationContext ctx, PropertyInfo prop, CorValRef th
}
}
- public override ObjectValueFlags Flags {
- get {
- ObjectValueFlags flags = ObjectValueFlags.Property;
- MethodInfo mi = prop.GetGetMethod () ?? prop.GetSetMethod ();
+ internal static ObjectValueFlags GetFlags (PropertyInfo prop)
+ {
+ ObjectValueFlags flags = ObjectValueFlags.Property;
+ MethodInfo mi = prop.GetGetMethod () ?? prop.GetSetMethod ();
- if (prop.GetSetMethod (true) == null)
- flags |= ObjectValueFlags.ReadOnly;
+ if (prop.GetSetMethod (true) == null)
+ flags |= ObjectValueFlags.ReadOnly;
- if (mi.IsStatic)
- flags |= ObjectValueFlags.Global;
+ if (mi.IsStatic)
+ flags |= ObjectValueFlags.Global;
- if (mi.IsFamilyAndAssembly)
- flags |= ObjectValueFlags.Internal;
- else if (mi.IsFamilyOrAssembly)
- flags |= ObjectValueFlags.InternalProtected;
- else if (mi.IsFamily)
- flags |= ObjectValueFlags.Protected;
- else if (mi.IsPublic)
- flags |= ObjectValueFlags.Public;
- else
- flags |= ObjectValueFlags.Private;
+ if (mi.IsFamilyAndAssembly)
+ flags |= ObjectValueFlags.Internal;
+ else if (mi.IsFamilyOrAssembly)
+ flags |= ObjectValueFlags.InternalProtected;
+ else if (mi.IsFamily)
+ flags |= ObjectValueFlags.Protected;
+ else if (mi.IsPublic)
+ flags |= ObjectValueFlags.Public;
+ else
+ flags |= ObjectValueFlags.Private;
- if (!prop.CanWrite)
- flags |= ObjectValueFlags.ReadOnly;
+ if (!prop.CanWrite)
+ flags |= ObjectValueFlags.ReadOnly;
+ return flags;
+ }
+
+ public override ObjectValueFlags Flags {
+ get {
return flags;
}
}
Commit: aff8fef13243a565ee3b475e991fe2fea6b918e8
Author: Therzok <[email protected]> (Therzok)
Date: 2013-11-05 18:51:47 GMT
URL: https://github.com/mono/monodevelop/commit/aff8fef13243a565ee3b475e991fe2fea6b918e8
[CorDebug] Implement reading of interfaces.
Changed paths:
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataType.cs
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/debug/Debugger.cs
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataType.cs
===================================================================
@@ -225,7 +225,26 @@ public override Type BaseType
// token, depending on the nature and location of the base type.
//
// See ECMA Partition II for more details.
- throw new NotImplementedException();
+ if (m_typeToken == 0)
+ throw new NotImplementedException ();
+
+ var token = new MetadataToken(m_typeToken);
+ int size;
+ TypeAttributes pdwTypeDefFlags;
+ int ptkExtends;
+
+ m_importer.GetTypeDefProps (token,
+ null,
+ 0,
+ out size,
+ out pdwTypeDefFlags,
+ out ptkExtends
+ );
+
+ if (ptkExtends == 0)
+ return null;
+
+ return new MetadataType (m_importer, ptkExtends);
}
}
@@ -464,6 +483,7 @@ public override Type GetInterface(String name, bool ignoreCase)
throw new NotImplementedException();
}
+ // TODO: Implement
public override Type[] GetInterfaces()
{
throw new NotImplementedException();
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/debug/Debugger.cs
===================================================================
@@ -1936,7 +1936,7 @@ abstract public class ManagedCallbackBase : ICorDebugManagedCallback, ICorDebugM
{
HandleEvent(ManagedCallbackType.OnProcessExit,
new CorProcessEventArgs(process == null ? null : CorProcess.GetCorProcess(process),
- ManagedCallbackType.OnProcessExit));
+ ManagedCallbackType.OnProcessExit) { Continue = false });
}
void ICorDebugManagedCallback.CreateThread(
Commit: 2fb4da89391a17470f68a510590166e929e858b8
Author: Therzok <[email protected]> (Therzok)
Date: 2013-11-05 18:51:48 GMT
URL: https://github.com/mono/monodevelop/commit/2fb4da89391a17470f68a510590166e929e858b8
[CorDebug] Removed a hackfix and removed duplicate member enumeration.
Changed paths:
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataFieldInfo.cs
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataType.cs
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataFieldInfo.cs
===================================================================
@@ -77,8 +77,7 @@ private static object ParseDefaultValue(MetadataType declaringType, IntPtr ppvSi
Debug.Assert(callingConv == CorCallingConvention.Field);
CorElementType elementType = MetadataHelperFunctions.CorSigUncompressElementType(ref ppvSigTemp);
- // TODO: Check this:
- if (elementType == CorElementType.ELEMENT_TYPE_END || elementType == CorElementType.ELEMENT_TYPE_VALUETYPE)
+ if (elementType == CorElementType.ELEMENT_TYPE_VALUETYPE)
//if (elementType == CorElementType.ELEMENT_TYPE_VALUETYPE)
{
uint token = MetadataHelperFunctions.CorSigUncompressToken(ref ppvSigTemp);
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataType.cs
===================================================================
@@ -508,7 +508,6 @@ public override FieldInfo[] GetFields(BindingFlags bindingAttr)
m_importer.EnumFields(ref hEnum,(int)m_typeToken,out fieldToken,1,out size);
if(size==0)
break;
- al.Add(new MetadataFieldInfo(m_importer,fieldToken,this));
// [Xamarin] Expression evaluator.
var field = new MetadataFieldInfo (m_importer, fieldToken, this);
if (MetadataExtensions.TypeFlagsMatch (field.IsPublic, field.IsStatic, bindingAttr))
Commit: 95f064ad2fbb39fd192a574235c9f1a5ae35c718
Author: Therzok <[email protected]> (Therzok)
Date: 2013-11-05 18:51:48 GMT
URL: https://github.com/mono/monodevelop/commit/95f064ad2fbb39fd192a574235c9f1a5ae35c718
[Cordebug] Fix issues with interface listing. Also cache GetType queries.
Changed paths:
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi/IMetadataImport.cs
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataType.cs
M main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorObjectAdaptor.cs
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi/IMetadataImport.cs
===================================================================
@@ -42,10 +42,15 @@ public interface IMetadataImport
[ComAliasName("mdTypeDef*")] out int rTypeDefs,
uint cMax /*must be 1*/,
[ComAliasName("ULONG*")] out uint pcTypeDefs);
-#if !MDBG_FAKE_COM
+
//STDMETHOD(EnumInterfaceImpls)(HCORENUM *phEnum, mdTypeDef td, mdInterfaceImpl rImpls[], ULONG cMax, ULONG* pcImpls) PURE;
- void EnumInterfaceImpls_(IntPtr phEnum, int td);
-
+ void EnumInterfaceImpls(
+ ref IntPtr phEnum,
+ int td,
+ [ComAliasName("mdInterfaceImpl*")] out int rImpls,
+ uint cMax /*must be 1*/,
+ [ComAliasName("ULONG*")] out uint pcImpls);
+#if !MDBG_FAKE_COM
//STDMETHOD(EnumTypeRefs)(HCORENUM *phEnum, mdTypeRef rTypeRefs[], ULONG cMax, ULONG* pcTypeRefs) PURE;
void EnumTypeRefs_();
#endif
@@ -640,10 +645,16 @@ public interface IMetadataImport2 : IMetadataImport
[ComAliasName("mdTypeDef*")] out int rTypeDefs,
uint cMax /*must be 1*/,
[ComAliasName("ULONG*")] out uint pcTypeDefs);
-#if !MDBG_FAKE_COM
+
//STDMETHOD(EnumInterfaceImpls)(HCORENUM *phEnum, mdTypeDef td, mdInterfaceImpl rImpls[], ULONG cMax, ULONG* pcImpls) PURE;
- new void EnumInterfaceImpls_(IntPtr phEnum, int td);
+ new void EnumInterfaceImpls(
+ ref IntPtr phEnum,
+ int td,
+ [ComAliasName("mdInterfaceImpl*")] out int rImpls,
+ uint cMax /*must be 1*/,
+ [ComAliasName("ULONG*")] out uint pcImpls);
+#if !MDBG_FAKE_COM
//STDMETHOD(EnumTypeRefs)(HCORENUM *phEnum, mdTypeRef rTypeRefs[], ULONG cMax, ULONG* pcTypeRefs) PURE;
new void EnumTypeRefs_();
#endif
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataType.cs
===================================================================
@@ -486,7 +486,26 @@ public override Type GetInterface(String name, bool ignoreCase)
// TODO: Implement
public override Type[] GetInterfaces()
{
- throw new NotImplementedException();
+ var al = new ArrayList();
+ var hEnum = new IntPtr();
+
+ int impl;
+ try
+ {
+ while(true)
+ {
+ uint size;
+ m_importer.EnumInterfaceImpls (ref hEnum,(int)m_typeToken,out impl,1,out size);
+ if(size==0)
+ break;
+ al.Add (new MetadataType (m_importer, impl));
+ }
+ }
+ finally
+ {
+ m_importer.CloseEnum(hEnum);
+ }
+ return (Type[]) al.ToArray(typeof(Type));
}
public override FieldInfo GetField(String name, BindingFlags bindingAttr)
@@ -496,8 +515,8 @@ public override FieldInfo GetField(String name, BindingFlags bindingAttr)
public override FieldInfo[] GetFields(BindingFlags bindingAttr)
{
- ArrayList al = new ArrayList();
- IntPtr hEnum = new IntPtr();
+ var al = new ArrayList();
+ var hEnum = new IntPtr();
int fieldToken;
try
Modified: main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorObjectAdaptor.cs
===================================================================
@@ -156,19 +156,27 @@ static IEnumerable<Type> GetAllTypes (EvaluationContext gctx)
}
}
+ Dictionary<string, CorType> typeCache = new Dictionary<string, CorType> ();
public override object GetType (EvaluationContext gctx, string name, object[] gtypeArgs)
{
+ CorType fastRet;
+ if (typeCache.TryGetValue (name, out fastRet))
+ return fastRet;
+
CorType[] typeArgs = CastArray<CorType> (gtypeArgs);
CorEvaluationContext ctx = (CorEvaluationContext) gctx;
foreach (CorModule mod in ctx.Session.GetModules ()) {
CorMetadataImport mi = ctx.Session.GetMetadataForModule (mod.Name);
if (mi != null) {
- foreach (Type t in mi.DefinedTypes)
+ foreach (Type t in mi.DefinedTypes) {
if (t.FullName == name) {
CorClass cls = mod.GetClassFromToken (t.MetadataToken);
- return cls.GetParameterizedType (CorElementType.ELEMENT_TYPE_CLASS, typeArgs);
+ fastRet = cls.GetParameterizedType (CorElementType.ELEMENT_TYPE_CLASS, typeArgs);
+ typeCache [name] = fastRet;
+ return fastRet;
}
+ }
}
}
return null;
@@ -925,8 +933,17 @@ protected override IEnumerable<ValueReference> GetMembers (EvaluationContext ctx
while (t != null) {
Type type = t.GetTypeInfo (cctx.Session);
- foreach (FieldInfo field in type.GetFields (bindingFlags))
+ foreach (FieldInfo field in type.GetFields (bindingFlags)) {
+ if (field.IsStatic && ((bindingFlags & BindingFlags.Static) == 0))
+ continue;
+ if (!field.IsStatic && ((bindingFlags & BindingFlags.Instance) == 0))
+ continue;
+ if (field.IsPublic && ((bindingFlags & BindingFlags.Public) == 0))
+ continue;
+ if (!field.IsPublic && ((bindingFlags & BindingFlags.NonPublic) == 0))
+ continue;
yield return new FieldReference (ctx, val, t, field);
+ }
foreach (PropertyInfo prop in type.GetProperties (bindingFlags)) {
MethodInfo mi = null;
@@ -938,6 +955,15 @@ protected override IEnumerable<ValueReference> GetMembers (EvaluationContext ctx
if (mi == null || mi.GetParameters ().Length != 0 || mi.IsAbstract)
continue;
+ if (mi.IsStatic && ((bindingFlags & BindingFlags.Static) == 0))
+ continue;
+ if (!mi.IsStatic && ((bindingFlags & BindingFlags.Instance) == 0))
+ continue;
+ if (mi.IsPublic && ((bindingFlags & BindingFlags.Public) == 0))
+ continue;
+ if (!mi.IsPublic && ((bindingFlags & BindingFlags.NonPublic) == 0))
+ continue;
+
// If a property is overriden, return the override instead of the base property
PropertyInfo overridden;
if (mi.IsVirtual && subProps.TryGetValue (prop.Name, out overridden)) {
@@ -957,6 +983,68 @@ protected override IEnumerable<ValueReference> GetMembers (EvaluationContext ctx
}
}
+ static T FindByName<T> (IEnumerable<T> elems, Func<T,string> getName, string name, bool caseSensitive)
+ {
+ T best = default(T);
+ foreach (T t in elems) {
+ string n = getName (t);
+ if (n == name)
+ return t;
+ if (!caseSensitive && n.Equals (name, StringComparison.CurrentCultureIgnoreCase))
+ best = t;
+ }
+ return best;
+ }
+
+ static bool IsStatic (PropertyInfo prop)
+ {
+ MethodInfo met = prop.GetGetMethod (true) ?? prop.GetSetMethod (true);
+ return met.IsStatic;
+ }
+
+ static bool IsAnonymousType (Type type)
+ {
+ return type.Name.StartsWith ("<>__AnonType", StringComparison.Ordinal);
+ }
+
+ static bool IsCompilerGenerated (FieldInfo field)
+ {
+ return field.GetCustomAttributes (true).Any (v => v is System.Diagnostics.DebuggerHiddenAttribute);
+ }
+
+ protected override ValueReference GetMember (EvaluationContext ctx, object t, object co, string name)
+ {
+ var cctx = ctx as CorEvaluationContext;
+ var type = t as CorType;
+
+ while (type != null) {
+ var tt = type.GetTypeInfo (cctx.Session);
+ FieldInfo field = FindByName (tt.GetFields (), f => f.Name, name, ctx.CaseSensitive);
+ if (field != null && (field.IsStatic || co != null))
+ return new FieldReference (ctx, co as CorValRef, type, field);
+
+ PropertyInfo prop = FindByName (tt.GetProperties (), p => p.Name, name, ctx.CaseSensitive);
+ if (prop != null && (IsStatic (prop) || co != null)) {
+ // Optimization: if the property has a CompilerGenerated backing field, use that instead.
+ // This way we avoid overhead of invoking methods on the debugee when the value is requested.
+ string cgFieldName = string.Format ("<{0}>{1}", prop.Name, IsAnonymousType (tt) ? "" : "k__BackingField");
+ if ((field = FindByName (tt.GetFields (), f => f.Name, cgFieldName, true)) != null && IsCompilerGenerated (field))
+ return new FieldReference (ctx, co as CorValRef, type, field); // FIXME: Support other types
+
+ // Backing field not available, so do things the old fashioned way.
+ MethodInfo getter = prop.GetGetMethod (true);
+ if (getter == null)
+ return null;
+
+ return new PropertyReference (ctx, prop, co as CorValRef, type);
+ }
+
+ type = type.Base;
+ }
+
+ return null;
+ }
+
static bool IsIEnumerable (Type type)
{
if (!type.IsInterface)
@@ -1299,6 +1387,47 @@ public override bool IsExternalType (EvaluationContext ctx, object type)
return base.IsExternalType (ctx, type);
}
- // TODO: Implement IsTypeLoaded, ForceTypeLoad
+ public override bool IsTypeLoaded (EvaluationContext ctx, string typeName)
+ {
+ return ctx.Adapter.GetType (ctx, typeName) != null;
+ }
+
+ public override bool IsTypeLoaded (EvaluationContext ctx, object type)
+ {
+ CorType ret;
+ var t = type as Type;
+
+ return IsTypeLoaded (ctx, t.FullName);
+ }
+
+ public override bool ForceLoadType (EvaluationContext ctx, object type)
+ {
+ // FIXME: Search for a proper way to do this.
+/* CorEvaluationContext gctx = (CorEvaluationContext) ctx;
+ Type tm = (Type) type;
+ CorType ret;
+
+ if (typeCache.TryGetValue (tm.FullName, out ret))
+ return true;
+
+ if (!tm.Attributes.HasFlag (TypeAttributes.BeforeFieldInit))
+ return false;
+
+ ret = GetType (ctx, tm.FullName) as CorType;
+
+ MethodInfo cctor = OverloadResolve (gctx, GetTypeName (ctx, ret), ".cctor", null, new List<MethodInfo>(), false);
+ if (cctor == null)
+ return true;
+
+ try {
+ RuntimeInvoke (ctx, ret, null, ".cctor", null, null);
+ } catch {
+ return false;
+ }
+
+ return true;*/
+ }
+
+ // TODO: Implement GetHoistedLocalVariables
}
}
Commit: d4b2b5f63baa603cfea65bf77e9e68a090615a4c
Author: Therzok <[email protected]> (Therzok)
Date: 2013-11-05 18:51:49 GMT
URL: https://github.com/mono/monodevelop/commit/d4b2b5f63baa603cfea65bf77e9e68a090615a4c
[CorDebug] Implemented isCompilerGenerated check for Type Display Data.
Changed paths:
M main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorObjectAdaptor.cs
Modified: main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorObjectAdaptor.cs
===================================================================
@@ -44,6 +44,7 @@
using CorElementType = Microsoft.Samples.Debugging.CorDebug.NativeApi.CorElementType;
using Microsoft.Samples.Debugging.Extensions;
using System.Linq;
+using System.Runtime.CompilerServices;
namespace MonoDevelop.Debugger.Win32
{
@@ -1321,14 +1322,13 @@ protected override TypeDisplayData OnGetTypeDisplayData (EvaluationContext ctx,
if (t == null)
return null;
- // FIXME: find out how to implement CompilerGenerated.
- //bool isCompilerGenerated = false;
string proxyType = null;
string nameDisplayString = null;
string typeDisplayString = null;
string valueDisplayString = null;
Dictionary<string, DebuggerBrowsableState> memberData = null;
bool hasTypeData = false;
+ bool isCompilerGenerated = false;
try {
foreach (object att in t.GetCustomAttributes (false)) {
@@ -1346,6 +1346,11 @@ protected override TypeDisplayData OnGetTypeDisplayData (EvaluationContext ctx,
valueDisplayString = datt.Value;
continue;
}
+ CompilerGeneratedAttribute cgatt = att as CompilerGeneratedAttribute;
+ if (cgatt != null) {
+ isCompilerGenerated = true;
+ continue;
+ }
}
ArrayList mems = new ArrayList ();
@@ -1355,7 +1360,7 @@ protected override TypeDisplayData OnGetTypeDisplayData (EvaluationContext ctx,
foreach (MemberInfo m in mems) {
object[] atts = m.GetCustomAttributes (typeof (DebuggerBrowsableAttribute), false);
if (atts.Length == 0) {
- atts = m.GetCustomAttributes (typeof (System.Runtime.CompilerServices.CompilerGeneratedAttribute), false);
+ atts = m.GetCustomAttributes (typeof (CompilerGeneratedAttribute), false);
if (atts.Length > 0)
atts[0] = new DebuggerBrowsableAttribute (DebuggerBrowsableState.Never);
}
@@ -1370,7 +1375,7 @@ protected override TypeDisplayData OnGetTypeDisplayData (EvaluationContext ctx,
ctx.WriteDebuggerError (ex);
}
if (hasTypeData)
- return new TypeDisplayData (proxyType, valueDisplayString, typeDisplayString, nameDisplayString, false, memberData);
+ return new TypeDisplayData (proxyType, valueDisplayString, typeDisplayString, nameDisplayString, isCompilerGenerated, memberData);
else
return null;
}
@@ -1394,40 +1399,9 @@ public override bool IsTypeLoaded (EvaluationContext ctx, string typeName)
public override bool IsTypeLoaded (EvaluationContext ctx, object type)
{
- CorType ret;
var t = type as Type;
-
return IsTypeLoaded (ctx, t.FullName);
}
-
- public override bool ForceLoadType (EvaluationContext ctx, object type)
- {
- // FIXME: Search for a proper way to do this.
-/* CorEvaluationContext gctx = (CorEvaluationContext) ctx;
- Type tm = (Type) type;
- CorType ret;
-
- if (typeCache.TryGetValue (tm.FullName, out ret))
- return true;
-
- if (!tm.Attributes.HasFlag (TypeAttributes.BeforeFieldInit))
- return false;
-
- ret = GetType (ctx, tm.FullName) as CorType;
-
- MethodInfo cctor = OverloadResolve (gctx, GetTypeName (ctx, ret), ".cctor", null, new List<MethodInfo>(), false);
- if (cctor == null)
- return true;
-
- try {
- RuntimeInvoke (ctx, ret, null, ".cctor", null, null);
- } catch {
- return false;
- }
-
- return true;*/
- }
-
// TODO: Implement GetHoistedLocalVariables
}
}
Commit: 931238508cb837cf5f57e98847025a373df1b7bd
Author: Therzok <[email protected]> (Therzok)
Date: 2013-11-05 18:54:36 GMT
URL: https://github.com/mono/monodevelop/commit/931238508cb837cf5f57e98847025a373df1b7bd
[CorDebug] Implement single getfield and fixed issue with properties whenever getter/setter was missing.
Changed paths:
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataFieldInfo.cs
M main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataType.cs
M main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorObjectAdaptor.cs
M main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/FieldReference.cs
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataFieldInfo.cs
===================================================================
@@ -78,7 +78,6 @@ private static object ParseDefaultValue(MetadataType declaringType, IntPtr ppvSi
CorElementType elementType = MetadataHelperFunctions.CorSigUncompressElementType(ref ppvSigTemp);
if (elementType == CorElementType.ELEMENT_TYPE_VALUETYPE)
- //if (elementType == CorElementType.ELEMENT_TYPE_VALUETYPE)
{
uint token = MetadataHelperFunctions.CorSigUncompressToken(ref ppvSigTemp);
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataType.cs
===================================================================
@@ -447,7 +447,7 @@ public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
MethodInfo mi = prop.GetGetMethod () ?? prop.GetSetMethod ();
if (mi == null)
continue;
- if (FlagsMatch (mi.IsPublic, mi.IsStatic, bindingAttr))
+ if (MetadataExtensions.TypeFlagsMatch (mi.IsPublic, mi.IsStatic, bindingAttr))
al.Add (prop);
}
catch {
@@ -510,7 +510,11 @@ public override Type[] GetInterfaces()
public override FieldInfo GetField(String name, BindingFlags bindingAttr)
{
- throw new NotImplementedException();
+ foreach (var field in GetFields (bindingAttr)) {
+ if (field.Name == name)
+ return field;
+ }
+ return null;
}
public override FieldInfo[] GetFields(BindingFlags bindingAttr)
Modified: main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorObjectAdaptor.cs
===================================================================
@@ -96,7 +96,17 @@ public override bool IsValueType (object type)
public override bool IsClass (EvaluationContext ctx, object type)
{
- return ((CorType)type).Type == CorElementType.ELEMENT_TYPE_CLASS && ((CorType)type).Class != null;
+ var t = (CorType) type;
+ var cctx = (CorEvaluationContext)ctx;
+ Type tt;
+ // Primitive check
+ if (MetadataHelperFunctionsExtensions.CoreTypes.TryGetValue (t.Type, out tt))
+ return false;
+
+ if (IsIEnumerable (t, cctx.Session))
+ return false;
+
+ return (t.Type == CorElementType.ELEMENT_TYPE_CLASS && t.Class != null) || IsValueType (t);
}
public override bool IsGenericType (EvaluationContext ctx, object type)
@@ -314,10 +324,10 @@ CorValRef Box (CorEvaluationContext ctx, CorValRef val)
CorArrayValue array = CorObjectAdaptor.GetRealObject (ctx, arr) as CorArrayValue;
ArrayAdaptor realArr = new ArrayAdaptor (ctx, arr, array);
- realArr.SetElement (new int[] { 0 }, val);
+ realArr.SetElement (new [] { 0 }, val);
CorType at = (CorType) GetType (ctx, "System.Array");
- object[] argTypes = new object[] { GetType (ctx, "System.Int32") };
+ object[] argTypes = { GetType (ctx, "System.Int32") };
return (CorValRef)RuntimeInvoke (ctx, at, arr, "GetValue", argTypes, new object[] { CreateValue (ctx, 0) });
}
@@ -628,8 +638,8 @@ public object CreateEnum (EvaluationContext ctx, CorType type, object val)
{
object systemEnumType = GetType (ctx, "System.Enum");
object enumType = CreateTypeObject (ctx, type);
- object[] argTypes = new object[] { GetValueType (ctx, enumType), GetValueType (ctx, val) };
- object[] args = new object[] { enumType, val };
+ object[] argTypes = { GetValueType (ctx, enumType), GetValueType (ctx, val) };
+ object[] args = { enumType, val };
return RuntimeInvoke (ctx, systemEnumType, null, "ToObject", argTypes, args);
}
@@ -703,9 +713,8 @@ public override ICollectionAdaptor CreateArrayAdaptor (EvaluationContext ctx, ob
CorValue val = CorObjectAdaptor.GetRealObject (ctx, arr);
if (val is CorArrayValue)
- return new ArrayAdaptor (ctx, (CorValRef) arr, (CorArrayValue) val);
- else
- return null;
+ return new ArrayAdaptor (ctx, (CorValRef)arr, (CorArrayValue)val);
+ return null;
}
public override IStringAdaptor CreateStringAdaptor (EvaluationContext ctx, object str)
@@ -713,9 +722,8 @@ public override IStringAdaptor CreateStringAdaptor (EvaluationContext ctx, objec
CorValue val = CorObjectAdaptor.GetRealObject (ctx, str);
if (val is CorStringValue)
- return new StringAdaptor (ctx, (CorValRef) str, (CorStringValue) val);
- else
- return null;
+ return new StringAdaptor (ctx, (CorValRef)str, (CorStringValue)val);
+ return null;
}
public static CorValue GetRealObject (EvaluationContext cctx, object objr)
@@ -910,7 +918,7 @@ protected override IEnumerable<ValueReference> GetMembers (EvaluationContext ctx
if (gval != null && (bindingFlags & BindingFlags.Instance) != 0)
realType = GetValueType (ctx, gval) as CorType;
- if (t.Class == null)
+ if (t.Type == CorElementType.ELEMENT_TYPE_CLASS && t.Class == null)
yield break;
CorEvaluationContext cctx = (CorEvaluationContext) ctx;
@@ -1030,7 +1038,7 @@ protected override ValueReference GetMember (EvaluationContext ctx, object t, ob
// This way we avoid overhead of invoking methods on the debugee when the value is requested.
string cgFieldName = string.Format ("<{0}>{1}", prop.Name, IsAnonymousType (tt) ? "" : "k__BackingField");
if ((field = FindByName (tt.GetFields (), f => f.Name, cgFieldName, true)) != null && IsCompilerGenerated (field))
- return new FieldReference (ctx, co as CorValRef, type, field); // FIXME: Support other types
+ return new FieldReference (ctx, co as CorValRef, type, field, prop.Name, ObjectValueFlags.Property);
// Backing field not available, so do things the old fashioned way.
MethodInfo getter = prop.GetGetMethod (true);
@@ -1048,9 +1056,6 @@ protected override ValueReference GetMember (EvaluationContext ctx, object t, ob
static bool IsIEnumerable (Type type)
{
- if (!type.IsInterface)
- return false;
-
if (type.Namespace == "System.Collections" && type.Name == "IEnumerable")
return true;
@@ -1113,6 +1118,7 @@ protected override CompletionData GetMemberCompletionData (EvaluationContext ctx
type = type.Base;
}
+ type = vr.Type as CorType;
t = type.GetTypeInfo (cctx.Session);
foreach (var iface in t.GetInterfaces ()) {
if (!isEnumerable && IsIEnumerable (iface)) {
@@ -1315,9 +1321,9 @@ IEnumerable<ValueReference> GetLocals (CorEvaluationContext ctx, ISymbolScope sc
protected override TypeDisplayData OnGetTypeDisplayData (EvaluationContext ctx, object gtype)
{
- CorType type = (CorType) gtype;
+ var type = (CorType) gtype;
- CorEvaluationContext wctx = (CorEvaluationContext) ctx;
+ var wctx = (CorEvaluationContext) ctx;
Type t = type.GetTypeInfo (wctx.Session);
if (t == null)
return null;
Modified: main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/FieldReference.cs
===================================================================
@@ -39,22 +39,28 @@ public class FieldReference: ValueReference
readonly CorValRef thisobj;
readonly CorValRef.ValueLoader loader;
readonly ObjectValueFlags flags;
+ readonly string vname;
- public FieldReference (EvaluationContext ctx, CorValRef thisobj, CorType type, FieldInfo field)
- : base (ctx)
+ public FieldReference (EvaluationContext ctx, CorValRef thisobj, CorType type, FieldInfo field, string vname, ObjectValueFlags vflags) : base (ctx)
{
this.thisobj = thisobj;
this.type = type;
this.field = field;
+ this.vname = vname;
if (field.IsStatic)
this.thisobj = null;
- flags = GetFlags (field);
+ flags = vflags | GetFlags (field);
loader = delegate {
return ((CorValRef)Value).Val;
};
}
+
+ public FieldReference (EvaluationContext ctx, CorValRef thisobj, CorType type, FieldInfo field)
+ : this (ctx, thisobj, type, field, null, ObjectValueFlags.Field)
+ {
+ }
public override object Type {
get {
@@ -78,25 +84,33 @@ public FieldReference (EvaluationContext ctx, CorValRef thisobj, CorType type, F
public override object Value {
get {
- CorEvaluationContext ctx = (CorEvaluationContext) Context;
- if (thisobj != null && !field.IsStatic) {
- CorObjectValue cval = (CorObjectValue) CorObjectAdaptor.GetRealObject (ctx, thisobj);
- CorValue val = cval.GetFieldValue (type.Class, field.MetadataToken);
- return new CorValRef (val, loader);
- }
- else {
- if (field.IsLiteral && field.IsStatic) {
- object oval = field.GetValue (null);
- CorObjectAdaptor ad = ctx.Adapter;
- // When getting enum members, convert the integer value to an enum value
- if (ad.IsEnum (ctx, type))
- return ad.CreateEnum (ctx, type, Context.Adapter.CreateValue (ctx, oval));
-
- return Context.Adapter.CreateValue (ctx, oval);
+ var ctx = (CorEvaluationContext) Context;
+ CorValue val;
+ if (thisobj != null && !field.IsStatic) {
+ CorObjectValue cval;
+ val = CorObjectAdaptor.GetRealObject (ctx, thisobj);
+ if (val is CorObjectValue) {
+ cval = (CorObjectValue)val;
+ val = cval.GetFieldValue (type.Class, field.MetadataToken);
+ return new CorValRef (val, loader);
+ }
+ else if (val is CorReferenceValue) {
+ CorReferenceValue rval = (CorReferenceValue)val;
+ return new CorValRef (val, loader);
}
- CorValue val = type.GetStaticFieldValue (field.MetadataToken, ctx.Frame);
- return new CorValRef (val, loader);
}
+
+ if (field.IsLiteral && field.IsStatic) {
+ object oval = field.GetValue (null);
+ CorObjectAdaptor ad = ctx.Adapter;
+ // When getting enum members, convert the integer value to an enum value
+ if (ad.IsEnum (ctx, type))
+ return ad.CreateEnum (ctx, type, Context.Adapter.CreateValue (ctx, oval));
+
+ return Context.Adapter.CreateValue (ctx, oval);
+ }
+ val = type.GetStaticFieldValue (field.MetadataToken, ctx.Frame);
+ return new CorValRef (val, loader);
}
set {
((CorValRef)Value).SetValue (Context, (CorValRef) value);
@@ -111,7 +125,7 @@ public FieldReference (EvaluationContext ctx, CorValRef thisobj, CorType type, F
public override string Name {
get {
- return field.Name;
+ return vname ?? field.Name;
}
}
Commit: 97577eabbace90acf9d6087be84e2a3d18c18ba0
Author: Therzok <[email protected]> (Therzok)
Date: 2013-11-05 18:54:38 GMT
URL: https://github.com/mono/monodevelop/commit/97577eabbace90acf9d6087be84e2a3d18c18ba0
[CorDebug] Hoisted reference support.
Changed paths:
M main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorObjectAdaptor.cs
M main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/FieldReference.cs
Modified: main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/CorObjectAdaptor.cs
===================================================================
@@ -1183,12 +1183,122 @@ public override object TargetObjectToObject (EvaluationContext ctx, object objr)
return base.TargetObjectToObject (ctx, objr);
}
- protected override ValueReference OnGetThisReference (EvaluationContext gctx)
+ static bool InGeneratedClosureOrIteratorType (CorEvaluationContext ctx)
{
- CorEvaluationContext ctx = (CorEvaluationContext) gctx;
- if (ctx.Frame.FrameType != CorFrameType.ILFrame || ctx.Frame.Function == null)
+ MethodInfo mi = ctx.Frame.Function.GetMethodInfo (ctx.Session);
+ if (mi == null || mi.IsStatic)
+ return false;
+
+ Type tm = mi.DeclaringType;
+ return IsGeneratedType (tm);
+ }
+
+ internal static bool IsGeneratedType (string name)
+ {
+ //
+ // This should cover all C# generated special containers
+ // - anonymous methods
+ // - lambdas
+ // - iterators
+ // - async methods
+ //
+ // which allow stepping into
+ //
+
+ return name[0] == '<' &&
+ // mcs is of the form <${NAME}>.c__{KIND}${NUMBER}
+ (name.IndexOf (">c__", StringComparison.Ordinal) > 0 ||
+ // csc is of form <${NAME}>d__${NUMBER}
+ name.IndexOf (">d__", StringComparison.Ordinal) > 0);
+ }
+
+ internal static bool IsGeneratedType (Type tm)
+ {
+ return IsGeneratedType (tm.Name);
+ }
+
+ ValueReference GetHoistedThisReference (CorEvaluationContext cx)
+ {
+ try {
+ CorValRef vref = new CorValRef (delegate {
+ return cx.Frame.GetArgument (0);
+ });
+ var type = (CorType) GetValueType (cx, vref);
+ return GetHoistedThisReference (cx, type, vref);
+ } catch (Exception) {
+ }
+ return null;
+ }
+
+ ValueReference GetHoistedThisReference (CorEvaluationContext cx, CorType type, object val)
+ {
+ Type t = type.GetTypeInfo (cx.Session);
+ var vref = (CorValRef)val;
+ foreach (FieldInfo field in t.GetFields ()) {
+ if (IsHoistedThisReference (field))
+ return new FieldReference (cx, vref, type, field, "this", ObjectValueFlags.Literal);
+
+ if (IsClosureReferenceField (field)) {
+ var fieldRef = new FieldReference (cx, vref, type, field);
+ var fieldType = (CorType)GetValueType (cx, fieldRef.Value);
+ var thisRef = GetHoistedThisReference (cx, fieldType, fieldRef.Value);
+ if (thisRef != null)
+ return thisRef;
+ }
+ }
+
+ return null;
+ }
+
+ static bool IsHoistedThisReference (FieldInfo field)
+ {
+ // mcs is "<>f__this" or "$this" (if in an async compiler generated type)
+ // csc is "<>4__this"
+ return field.Name == "$this" ||
+ (field.Name.StartsWith ("<>", StringComparison.Ordinal) &&
+ field.Name.EndsWith ("__this", StringComparison.Ordinal));
+ }
+
+ static bool IsClosureReferenceField (FieldInfo field)
+ {
+ // mcs is "<>f__ref"
+ // csc is "CS$<>"
+ return field.Name.StartsWith ("CS$<>", StringComparison.Ordinal) ||
+ field.Name.StartsWith ("<>f__ref", StringComparison.Ordinal);
+ }
+
+ static bool IsClosureReferenceLocal (ISymbolVariable local)
+ {
+ if (local.Name == null)
+ return false;
+
+ // mcs is "$locvar" or starts with '<'
+ // csc is "CS$<>"
+ return local.Name.Length == 0 || local.Name[0] == '<' || local.Name.StartsWith ("$locvar", StringComparison.Ordinal) ||
+ local.Name.StartsWith ("CS$<>", StringComparison.Ordinal);
+ }
+
+ static bool IsGeneratedTemporaryLocal (ISymbolVariable local)
+ {
+ // csc uses CS$ prefix for temporary variables and <>t__ prefix for async task-related state variables
+ return local.Name != null && (local.Name.StartsWith ("CS$", StringComparison.Ordinal) || local.Name.StartsWith ("<>t__", StringComparison.Ordinal));
+ }
+
+ protected override ValueReference OnGetThisReference (EvaluationContext ctx)
+ {
+ CorEvaluationContext cctx = (CorEvaluationContext) ctx;
+ if (cctx.Frame.FrameType != CorFrameType.ILFrame || cctx.Frame.Function == null)
return null;
+ if (InGeneratedClosureOrIteratorType (cctx))
+ return GetHoistedThisReference (cctx);
+
+ return GetThisReference (cctx);
+
+ }
+
+ ValueReference GetThisReference (CorEvaluationContext ctx)
+ {
MethodInfo mi = ctx.Frame.Function.GetMethodInfo (ctx.Session);
if (mi == null || mi.IsStatic)
return null;
@@ -1200,7 +1310,7 @@ protected override ValueReference OnGetThisReference (EvaluationContext gctx)
return new VariableReference (ctx, vref, "this", ObjectValueFlags.Variable | ObjectValueFlags.ReadOnly);
} catch (Exception e) {
- gctx.WriteDebuggerError (e);
+ ctx.WriteDebuggerError (e);
return null;
}
}
@@ -1242,14 +1352,76 @@ protected override IEnumerable<ValueReference> OnGetParameters (EvaluationContex
protected override IEnumerable<ValueReference> OnGetLocalVariables (EvaluationContext ctx)
{
- CorEvaluationContext wctx = (CorEvaluationContext) ctx;
+ CorEvaluationContext cctx = (CorEvaluationContext)ctx;
+ if (InGeneratedClosureOrIteratorType (cctx)) {
+ ValueReference vthis = GetThisReference (cctx);
+ return GetHoistedLocalVariables (cctx, vthis).Union (GetLocalVariables (cctx));
+ }
+
+ return GetLocalVariables (cctx);
+ }
+
+ IEnumerable<ValueReference> GetHoistedLocalVariables (CorEvaluationContext cx, ValueReference vthis)
+ {
+ if (vthis == null)
+ return new ValueReference [0];
+
+ object val = vthis.Value;
+ if (IsNull (cx, val))
+ return new ValueReference [0];
+
+ CorType tm = (CorType) vthis.Type;
+ Type t = tm.GetTypeInfo (cx.Session);
+ bool isIterator = IsGeneratedType (t);
+
+ var list = new List<ValueReference> ();
+ foreach (FieldInfo field in t.GetFields ()) {
+ if (IsHoistedThisReference (field))
+ continue;
+ if (IsClosureReferenceField (field)) {
+ list.AddRange (GetHoistedLocalVariables (cx, new FieldReference (cx, (CorValRef)val, tm, field)));
+ continue;
+ }
+ if (field.Name[0] == '<') {
+ if (isIterator) {
+ var name = GetHoistedIteratorLocalName (field);
+ if (!string.IsNullOrEmpty (name)) {
+ list.Add (new FieldReference (cx, (CorValRef)val, tm, field, name, ObjectValueFlags.Variable));
+ }
+ }
+ } else if (!field.Name.Contains ("$")) {
+ list.Add (new FieldReference (cx, (CorValRef)val, tm, field, field.Name, ObjectValueFlags.Variable));
+ }
+ }
+ return list;
+ }
+
+ static string GetHoistedIteratorLocalName (FieldInfo field)
+ {
+ //mcs captured args, of form <$>name
+ if (field.Name.StartsWith ("<$>", StringComparison.Ordinal)) {
+ return field.Name.Substring (3);
+ }
+
+ // csc, mcs locals of form <name>__0
+ if (field.Name[0] == '<') {
+ int i = field.Name.IndexOf ('>');
+ if (i > 1) {
+ return field.Name.Substring (1, i - 1);
+ }
+ }
+ return null;
+ }
+
+ IEnumerable<ValueReference> GetLocalVariables (CorEvaluationContext cx)
+ {
uint offset;
CorDebugMappingResult mr;
try {
- wctx.Frame.GetIP (out offset, out mr);
- return GetLocals (wctx, null, (int) offset, false);
+ cx.Frame.GetIP (out offset, out mr);
+ return GetLocals (cx, null, (int) offset, false);
} catch (Exception e) {
- ctx.WriteDebuggerError (e);
+ cx.WriteDebuggerError (e);
return null;
}
}
@@ -1302,9 +1474,18 @@ IEnumerable<ValueReference> GetLocals (CorEvaluationContext ctx, ISymbolScope sc
foreach (ISymbolVariable var in scope.GetLocals ()) {
if (var.Name == "$site")
continue;
- if (var.Name.IndexOfAny(new char[] {'$','<','>'}) == -1 || showHidden) {
+ if (IsClosureReferenceLocal (var) && IsGeneratedType (var.Name)) {
int addr = var.AddressField1;
- CorValRef vref = new CorValRef (delegate {
+ var vref = new CorValRef (delegate {
+ return ctx.Frame.GetLocalVariable (addr);
+ });
+
+ foreach (var gv in GetHoistedLocalVariables (ctx, new VariableReference (ctx, vref, var.Name, ObjectValueFlags.Variable))) {
+ yield return gv;
+ }
+ } else if (!IsGeneratedTemporaryLocal (var) || showHidden) {
+ int addr = var.AddressField1;
+ var vref = new CorValRef (delegate {
return ctx.Frame.GetLocalVariable (addr);
});
yield return new VariableReference (ctx, vref, var.Name, ObjectValueFlags.Variable);
Modified: main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/FieldReference.cs
===================================================================
@@ -94,9 +94,9 @@ public FieldReference (EvaluationContext ctx, CorValRef thisobj, CorType type, F
val = cval.GetFieldValue (type.Class, field.MetadataToken);
return new CorValRef (val, loader);
}
- else if (val is CorReferenceValue) {
+ if (val is CorReferenceValue) {
CorReferenceValue rval = (CorReferenceValue)val;
- return new CorValRef (val, loader);
+ return new CorValRef (rval, loader);
}
}
Commit: 4d6f4b0516ee20a1704638e9011532a94ce51212
Author: Therzok <[email protected]> (Therzok)
Date: 2013-11-05 18:54:38 GMT
URL: https://github.com/mono/monodevelop/commit/4d6f4b0516ee20a1704638e9011532a94ce51212
[CorDebug] Update readme.
Changed paths:
M main/src/addins/MonoDevelop.Debugger.Win32/README.txt
Modified: main/src/addins/MonoDevelop.Debugger.Win32/README.txt
===================================================================
@@ -1,9 +1,6 @@
CorApi and CorApi2 are samples taken from http://www.microsoft.com/en-us/download/details.aspx?id=19621 with our own API changes added to it.
-API changes are to be marked with [Xamarin] tags.
+Most sample changes are to be marked with [Xamarin] tags.
*For additions of properties or changes to existing properties, apply the tag to the property explaining the fix applied.
-API changes are to be done with tabs as it's easier to differentiate between their code and our code.
-
-Post-update API changes can be applied with this commit:
-5056a6ade8e0d0e8398c13dcbba734ea25419b87
+Most changes in samples are implementations of NotImplementedException or use of Extension code.
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches