Branch: refs/heads/newCorApi
Home: https://github.com/mono/monodevelop
Compare: https://github.com/mono/monodevelop/compare/545277dd36d9...ae89fc85d6f1
Commit: 72a1f157e1b59fdb6ed265c198e8b81993295794
Author: Therzok <[email protected]> (Therzok)
Date: 2013-10-31 15:32:10 GMT
URL: https://github.com/mono/monodevelop/commit/72a1f157e1b59fdb6ed265c198e8b81993295794
[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));
}
public override PropertyAttributes Attributes
@@ -169,7 +170,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,22 +413,20 @@ 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 ();
- if (mi == null)
- mi = prop.GetSetMethod ();
- if (FlagsMatch (mi.IsPublic, mi.IsStatic, bindingAttr))
+ MethodInfo mi = prop.GetGetMethod () ?? prop.GetSetMethod ();
+ if (MetadataExtensions.TypeFlagsMatch (mi.IsPublic, mi.IsStatic, bindingAttr))
al.Add (prop);
}
catch {
@@ -472,21 +472,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 +483,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 +500,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 +514,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 +618,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 +626,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: f33cb4cf842b9f81afe18657a593c62fc1492beb
Author: Therzok <[email protected]> (Therzok)
Date: 2013-10-31 15:32:10 GMT
URL: https://github.com/mono/monodevelop/commit/f33cb4cf842b9f81afe18657a593c62fc1492beb
[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: 0dca1b9956b90a064a363674d342b33fd39142ba
Author: Therzok <[email protected]> (Therzok)
Date: 2013-10-31 15:32:11 GMT
URL: https://github.com/mono/monodevelop/commit/0dca1b9956b90a064a363674d342b33fd39142ba
[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: 728054fe60168967270ae153773cfb7acb543b35
Author: Therzok <[email protected]> (Therzok)
Date: 2013-10-31 15:32:12 GMT
URL: https://github.com/mono/monodevelop/commit/728054fe60168967270ae153773cfb7acb543b35
[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: a5da093bdd6b9072d8df1e71d57b3316bbd007af
Author: Therzok <[email protected]> (Therzok)
Date: 2013-10-31 15:32:12 GMT
URL: https://github.com/mono/monodevelop/commit/a5da093bdd6b9072d8df1e71d57b3316bbd007af
[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);
}
}
@@ -462,6 +481,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: e0265b984bbd781ef097f6e32fa0ea9abb4f56ef
Author: Therzok <[email protected]> (Therzok)
Date: 2013-10-31 15:32:13 GMT
URL: https://github.com/mono/monodevelop/commit/e0265b984bbd781ef097f6e32fa0ea9abb4f56ef
[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
===================================================================
@@ -506,7 +506,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: a0645cb7ba7ef81a569015a6cfc6ab67bf83ea33
Author: Therzok <[email protected]> (Therzok)
Date: 2013-10-31 15:32:13 GMT
URL: https://github.com/mono/monodevelop/commit/a0645cb7ba7ef81a569015a6cfc6ab67bf83ea33
[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
===================================================================
@@ -484,7 +484,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)
@@ -494,8 +513,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: f3c4c5dbee8c2cc21713487d908a82b58f7427f2
Author: Therzok <[email protected]> (Therzok)
Date: 2013-10-31 15:32:14 GMT
URL: https://github.com/mono/monodevelop/commit/f3c4c5dbee8c2cc21713487d908a82b58f7427f2
[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: 83cd8f123117b51f1ad2db54768c0b108ae1b8c6
Author: Therzok <[email protected]> (Therzok)
Date: 2013-10-31 15:32:14 GMT
URL: https://github.com/mono/monodevelop/commit/83cd8f123117b51f1ad2db54768c0b108ae1b8c6
[CorDebug] 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/MetadataPropertyInfo.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/MetadataPropertyInfo.cs
===================================================================
@@ -109,10 +109,18 @@ public override MethodInfo[] GetAccessors (bool nonPublic)
public override MethodInfo GetGetMethod (bool nonPublic)
{
if (m_getter == null) {
- if (m_pmdGetter != 0)
- m_getter = new MetadataMethodInfo (m_importer, m_pmdGetter);
+ if (m_pmdGetter != 0) {
+ try {
+ m_getter = new MetadataMethodInfo (m_importer, m_pmdGetter);
+ } catch (ArgumentException) {
+ m_pmdGetter = 0;
+ return null;
+ }
+ }
}
- return m_getter;
+ if (nonPublic || m_getter.IsPublic)
+ return m_getter;
+ return null;
}
public override ParameterInfo[] GetIndexParameters ( )
@@ -126,10 +134,18 @@ public override ParameterInfo[] GetIndexParameters ( )
public override MethodInfo GetSetMethod (bool nonPublic)
{
if (m_setter == null) {
- if (m_pmdSetter != 0)
- m_setter = new MetadataMethodInfo (m_importer, m_pmdSetter);
+ if (m_pmdSetter != 0) {
+ try {
+ m_setter = new MetadataMethodInfo (m_importer, m_pmdSetter);
+ } catch (ArgumentException) {
+ m_pmdSetter = 0;
+ return null;
+ }
+ }
}
- return m_setter;
+ if (nonPublic || m_setter.IsPublic)
+ return m_setter;
+ return null;
}
public override object GetValue (object obj, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataType.cs
===================================================================
@@ -445,6 +445,8 @@ public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
var prop = new MetadataPropertyInfo (m_importer, methodToken, this);
try {
MethodInfo mi = prop.GetGetMethod () ?? prop.GetSetMethod ();
+ if (mi == null)
+ continue;
if (MetadataExtensions.TypeFlagsMatch (mi.IsPublic, mi.IsStatic, bindingAttr))
al.Add (prop);
}
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)
@@ -1030,7 +1040,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 +1058,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;
@@ -1315,9 +1322,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,23 @@ public FieldReference (EvaluationContext ctx, CorValRef thisobj, CorType type, F
public override object Value {
get {
- CorEvaluationContext ctx = (CorEvaluationContext) Context;
+ var 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);
+ return new CorValRef (cval.GetFieldValue (type.Class, field.MetadataToken), 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);
- }
- 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);
}
+ return new CorValRef (type.GetStaticFieldValue (field.MetadataToken, ctx.Frame), loader);
}
set {
((CorValRef)Value).SetValue (Context, (CorValRef) value);
@@ -111,7 +115,7 @@ public FieldReference (EvaluationContext ctx, CorValRef thisobj, CorType type, F
public override string Name {
get {
- return field.Name;
+ return vname ?? field.Name;
}
}
Commit: 98c42b2afcdc5bf96bb758a80cf41cd24bc0f5f0
Author: Therzok <[email protected]> (Therzok)
Date: 2013-10-31 15:32:15 GMT
URL: https://github.com/mono/monodevelop/commit/98c42b2afcdc5bf96bb758a80cf41cd24bc0f5f0
[CorDebug] Implement single getfield and better fix for property getter/setter issue.
Changed paths:
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/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/MetadataPropertyInfo.cs
===================================================================
@@ -84,6 +84,12 @@ internal MetadataPropertyInfo (IMetadataImport importer, int propertyToken, Meta
m_propAttributes = (PropertyAttributes) pdwPropFlags;
m_name = szProperty.ToString ();
MetadataHelperFunctionsExtensions.GetCustomAttribute (importer, propertyToken, typeof (System.Diagnostics.DebuggerBrowsableAttribute));
+
+ if (!m_importer.IsValidToken ((uint)m_pmdGetter))
+ m_pmdGetter = 0;
+
+ if (!m_importer.IsValidToken ((uint)m_pmdSetter))
+ m_pmdSetter = 0;
}
public override PropertyAttributes Attributes
@@ -108,16 +114,12 @@ public override MethodInfo[] GetAccessors (bool nonPublic)
public override MethodInfo GetGetMethod (bool nonPublic)
{
- if (m_getter == null) {
- if (m_pmdGetter != 0) {
- try {
- m_getter = new MetadataMethodInfo (m_importer, m_pmdGetter);
- } catch (ArgumentException) {
- m_pmdGetter = 0;
- return null;
- }
- }
- }
+ if (m_pmdGetter == 0)
+ return null;
+
+ if (m_getter == null)
+ m_getter = new MetadataMethodInfo (m_importer, m_pmdGetter);
+
if (nonPublic || m_getter.IsPublic)
return m_getter;
return null;
@@ -133,16 +135,12 @@ public override ParameterInfo[] GetIndexParameters ( )
public override MethodInfo GetSetMethod (bool nonPublic)
{
- if (m_setter == null) {
- if (m_pmdSetter != 0) {
- try {
- m_setter = new MetadataMethodInfo (m_importer, m_pmdSetter);
- } catch (ArgumentException) {
- m_pmdSetter = 0;
- return null;
- }
- }
- }
+ if (m_pmdSetter == 0)
+ return null;
+
+ if (m_setter == null)
+ m_setter = new MetadataMethodInfo (m_importer, m_pmdSetter);
+
if (nonPublic || m_setter.IsPublic)
return m_setter;
return null;
Modified: main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/Metadata/MetadataType.cs
===================================================================
@@ -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
===================================================================
@@ -324,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) });
}
@@ -638,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);
}
@@ -713,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)
@@ -723,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)
@@ -920,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;
@@ -1120,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)) {
Modified: main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/FieldReference.cs
===================================================================
@@ -85,10 +85,19 @@ public FieldReference (EvaluationContext ctx, CorValRef thisobj, CorType type, F
public override object Value {
get {
var ctx = (CorEvaluationContext) Context;
-
- if (thisobj != null && !field.IsStatic) {
- CorObjectValue cval = (CorObjectValue) CorObjectAdaptor.GetRealObject (ctx, thisobj);
- return new CorValRef (cval.GetFieldValue (type.Class, field.MetadataToken), loader);
+ 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);
+ }
}
if (field.IsLiteral && field.IsStatic) {
@@ -100,7 +109,8 @@ public FieldReference (EvaluationContext ctx, CorValRef thisobj, CorType type, F
return Context.Adapter.CreateValue (ctx, oval);
}
- return new CorValRef (type.GetStaticFieldValue (field.MetadataToken, ctx.Frame), loader);
+ val = type.GetStaticFieldValue (field.MetadataToken, ctx.Frame);
+ return new CorValRef (val, loader);
}
set {
((CorValRef)Value).SetValue (Context, (CorValRef) value);
Commit: 3adb219e271df79c6e9bb2692aee1c1ed1994c6d
Author: Therzok <[email protected]> (Therzok)
Date: 2013-10-31 15:32:16 GMT
URL: https://github.com/mono/monodevelop/commit/3adb219e271df79c6e9bb2692aee1c1ed1994c6d
[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: ae89fc85d6f16fac9418f0cb50b8e8ac373aff28
Author: Therzok <[email protected]> (Therzok)
Date: 2013-10-31 15:32:17 GMT
URL: https://github.com/mono/monodevelop/commit/ae89fc85d6f16fac9418f0cb50b8e8ac373aff28
[CorDebug] Update readme.
Changed paths:
M main/src/addins/MonoDevelop.Debugger.Win32/README.txt
Modified: main/src/addins/MonoDevelop.Debugger.Win32/README.txt
===================================================================
@@ -5,5 +5,4 @@ API changes are to be marked with [Xamarin] tags.
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 API changes are implementations of NotImplementedException or use of Extension code.
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.