pascalabcnet/VisualPascalABCNET/IB/Debugger/Utility.cs

261 lines
11 KiB
C#
Raw Normal View History

// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
2015-06-02 22:52:35 +03:00
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
2015-05-14 22:35:07 +03:00
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.IO;
using System.Threading;
using VisualPascalABCPlugins;
using VisualPascalABC.Utils;
using Debugger;
using System.Runtime.ExceptionServices;
namespace VisualPascalABC
{
public static class DebugUtils
{
private static Hashtable ht = new Hashtable();
2016-09-20 20:13:47 +03:00
private static Dictionary<Type, DebugType> type_cache = new Dictionary<Type, DebugType>();
2015-05-14 22:35:07 +03:00
static DebugUtils()
{
ht["System.Collections.ArrayList"] = ht;
ht["System.Collections.Hashtable"] = ht;
ht["System.Collections.Queue"] = ht;
ht["System.Collections.Stack"] = ht;
ht["System.Collections.SortedList"] = ht;
ht["System.Collections.Generic.List"] = ht;
ht["System.Collections.Generic.Dictionary"] = ht;
ht["System.Collections.Generic.Stack"] = ht;
ht["System.Collections.Generic.Queue"] = ht;
ht["System.Collections.Generic.SortedList"] = ht;
ht["System.Collections.Generic.SortedDictionary"] = ht;
ht["System.Collections.Generic.LinkedList"] = ht;
}
public static bool CheckForCollection(DebugType type)
{
string name = type.FullName;
int ind = name.IndexOf('<');
if (ind != -1) name = name.Substring(0, ind);
return ht[name] != null;
}
public static NamedValue GetNullBasedArray(Value val)
{
IList<FieldInfo> flds = val.Type.GetFields();
if (flds.Count != 3) return null;
foreach (FieldInfo fi in flds)
if (fi.Name == "NullBasedArray") return fi.GetValue(val);
return null;
}
public static MethodInfo GetMethod(DebugType t, string name)
{
return t.GetMember(name, Debugger.BindingFlags.All)[0] as MethodInfo;
}
public static PropertyInfo GetProperty(DebugType t, string name)
{
return t.GetMember(name, Debugger.BindingFlags.All)[0] as PropertyInfo;
}
public static DebugType GetDebugType(Type t)
{
Process p = WorkbenchServiceFactory.DebuggerManager.DebuggedProcess;
string name;
if (t.Assembly == typeof(int).Assembly)
name = "mscorlib.dll";
else
name = t.Assembly.ManifestModule.ScopeName;
2016-09-20 20:13:47 +03:00
DebugType dt = DebugType.Create(p.GetModule(name), (uint)t.MetadataToken);
return dt;
2015-05-14 22:35:07 +03:00
}
public static DebugType GetDebugType(Type t, List<DebugType> gen_args)
{
string name;
if (t.Assembly == typeof(int).Assembly)
name = "mscorlib.dll";
else
name = t.Assembly.ManifestModule.ScopeName;
return DebugType.Create(WorkbenchServiceFactory.DebuggerManager.DebuggedProcess.GetModule(name), (uint)t.MetadataToken, gen_args.ToArray());
}
public static bool IsQueue(DebugType type)
{
return type.FullName == "System.Collections.Queue" || type.FullName.StartsWith("System.Collections.Generic.Queue");
}
public static bool IsHashtable(DebugType type)
{
return type.FullName == "System.Collections.Hashtable";
}
public static bool IsLinkedList(DebugType type)
{
return type.FullName.StartsWith("System.Collections.Generic.LinkedList");
}
public static bool IsDictionary(DebugType type)
{
return type.FullName.StartsWith("System.Collections.Generic.Dictionary");
}
public static bool IsStack(DebugType type)
{
return type.FullName == "System.Collections.Stack" || type.FullName.StartsWith("System.Collections.Generic.Stack");
}
public static bool IsSortedList(DebugType type)
{
return type.FullName == "System.Collections.SortedList" || type.FullName.StartsWith("System.Collections.Generic.SortedList");
}
public static bool IsSortedDictionary(DebugType type)
{
return type.FullName.StartsWith("System.Collections.Generic.SortedDictionary");
}
public static string WrapTypeName(DebugType type)
{
if (type.IsArray)
Деактивация кнопок, связанных с Intellisense, для языков без Intellisense + разделение ILanguageInformation на два интерфейса (#3378) * Refactor language information classes * Implement SimpleLanguageInformation abstract class * Move some properties to SimpleLanguageInformation * Implement format and debug buttons disabling if Intellisense is not supported for current language * Add Intellisense available check in FormsExtensions to deactivate menu items if needed * Change function interfaces in VisibilityService * Replace CodeCompletionController.CurrentParser null checks with IntellisenseAvailable method call * Refactor IParser and BaseParser to deduplicate code * Fix BuildTreeInSpecialMode in SPythonParser * Add SimpleParser class for new languages without Intellisense * Delete duplicate SetDebugButtonsEnabled function * Add Intellisense available check in RunService when attaching debugger * Delete inner check in SetDebugButtonsEnabled to improve architecture * Change CurrentParser property in CodeCompletion to be CurrentLanguage * Divide ILanguageInformation into two interfaces (creating new ILanguageIntellisenseSupport) * Fix LanguageIntellisenseSupport initialization in BaseLanguage * Fix RunService fictive_attach logic * Disable Intellisense parsing for languages without Intellisense support * Add DefaultLanguageInformation abstract class * Add default implementation for SetSemanticConstants in BaseLanguage * Simplify IParser interface * Update developer guide documentation
2026-01-27 22:25:28 +03:00
if (WorkbenchServiceFactory.DebuggerManager.language != null)
return WorkbenchServiceFactory.DebuggerManager.language.LanguageIntellisenseSupport.GetArrayDescription(WrapTypeName(type.GetElementType()), type.GetArrayRank());
2015-05-14 22:35:07 +03:00
else
return "array of " + WrapTypeName(type.GetElementType());
return internalWrapTypeName(type.FullName);
}
[HandleProcessCorruptedStateExceptionsAttribute]
public static bool IsObject(Value nv)
{
try
{
return nv.IsObject;
}
catch (System.Exception e)
{
return false;
}
}
[HandleProcessCorruptedStateExceptionsAttribute]
public static bool IsEnum(Value nv, out int val)
{
val = 0;
try
{
if (IsObject(nv))
{
IList<FieldInfo> fields = nv.Type.GetFields(BindingFlags.All);
bool is_enum = true;
foreach (FieldInfo fi in fields)
{
if (!(fi.IsStatic && fi.IsLiteral))
{
if (fi.Name != "value__")
{
is_enum = false;
break;
}
else
val = (int)fi.GetValue(nv).PrimitiveValue;
}
}
if (fields.Count == 0) is_enum = false;
return is_enum;
}
return false;
}
catch
{
return false;
}
}
public static string WrapTypeName(Type t)
{
return internalWrapTypeName(t.FullName);
}
private static string internalWrapTypeName(string name)
{
Деактивация кнопок, связанных с Intellisense, для языков без Intellisense + разделение ILanguageInformation на два интерфейса (#3378) * Refactor language information classes * Implement SimpleLanguageInformation abstract class * Move some properties to SimpleLanguageInformation * Implement format and debug buttons disabling if Intellisense is not supported for current language * Add Intellisense available check in FormsExtensions to deactivate menu items if needed * Change function interfaces in VisibilityService * Replace CodeCompletionController.CurrentParser null checks with IntellisenseAvailable method call * Refactor IParser and BaseParser to deduplicate code * Fix BuildTreeInSpecialMode in SPythonParser * Add SimpleParser class for new languages without Intellisense * Delete duplicate SetDebugButtonsEnabled function * Add Intellisense available check in RunService when attaching debugger * Delete inner check in SetDebugButtonsEnabled to improve architecture * Change CurrentParser property in CodeCompletion to be CurrentLanguage * Divide ILanguageInformation into two interfaces (creating new ILanguageIntellisenseSupport) * Fix LanguageIntellisenseSupport initialization in BaseLanguage * Fix RunService fictive_attach logic * Disable Intellisense parsing for languages without Intellisense support * Add DefaultLanguageInformation abstract class * Add default implementation for SetSemanticConstants in BaseLanguage * Simplify IParser interface * Update developer guide documentation
2026-01-27 22:25:28 +03:00
if (WorkbenchServiceFactory.DebuggerManager.language != null)
2015-05-14 22:35:07 +03:00
switch (name)
{
Деактивация кнопок, связанных с Intellisense, для языков без Intellisense + разделение ILanguageInformation на два интерфейса (#3378) * Refactor language information classes * Implement SimpleLanguageInformation abstract class * Move some properties to SimpleLanguageInformation * Implement format and debug buttons disabling if Intellisense is not supported for current language * Add Intellisense available check in FormsExtensions to deactivate menu items if needed * Change function interfaces in VisibilityService * Replace CodeCompletionController.CurrentParser null checks with IntellisenseAvailable method call * Refactor IParser and BaseParser to deduplicate code * Fix BuildTreeInSpecialMode in SPythonParser * Add SimpleParser class for new languages without Intellisense * Delete duplicate SetDebugButtonsEnabled function * Add Intellisense available check in RunService when attaching debugger * Delete inner check in SetDebugButtonsEnabled to improve architecture * Change CurrentParser property in CodeCompletion to be CurrentLanguage * Divide ILanguageInformation into two interfaces (creating new ILanguageIntellisenseSupport) * Fix LanguageIntellisenseSupport initialization in BaseLanguage * Fix RunService fictive_attach logic * Disable Intellisense parsing for languages without Intellisense support * Add DefaultLanguageInformation abstract class * Add default implementation for SetSemanticConstants in BaseLanguage * Simplify IParser interface * Update developer guide documentation
2026-01-27 22:25:28 +03:00
case "System.Boolean": return WorkbenchServiceFactory.DebuggerManager.language.LanguageIntellisenseSupport.GetShortTypeName(typeof(bool));
case "System.Int32": return WorkbenchServiceFactory.DebuggerManager.language.LanguageIntellisenseSupport.GetShortTypeName(typeof(int));
case "System.Byte": return WorkbenchServiceFactory.DebuggerManager.language.LanguageIntellisenseSupport.GetShortTypeName(typeof(byte));
case "System.Double": return WorkbenchServiceFactory.DebuggerManager.language.LanguageIntellisenseSupport.GetShortTypeName(typeof(double));
case "System.String": return WorkbenchServiceFactory.DebuggerManager.language.LanguageIntellisenseSupport.GetShortTypeName(typeof(string));
case "System.Char": return WorkbenchServiceFactory.DebuggerManager.language.LanguageIntellisenseSupport.GetShortTypeName(typeof(char));
case "System.SByte": return WorkbenchServiceFactory.DebuggerManager.language.LanguageIntellisenseSupport.GetShortTypeName(typeof(sbyte));
case "System.Int16": return WorkbenchServiceFactory.DebuggerManager.language.LanguageIntellisenseSupport.GetShortTypeName(typeof(short));
case "System.UInt16": return WorkbenchServiceFactory.DebuggerManager.language.LanguageIntellisenseSupport.GetShortTypeName(typeof(ushort));
case "System.UInt32": return WorkbenchServiceFactory.DebuggerManager.language.LanguageIntellisenseSupport.GetShortTypeName(typeof(uint));
case "System.Int64": return WorkbenchServiceFactory.DebuggerManager.language.LanguageIntellisenseSupport.GetShortTypeName(typeof(long));
case "System.UInt64": return WorkbenchServiceFactory.DebuggerManager.language.LanguageIntellisenseSupport.GetShortTypeName(typeof(ulong));
case "System.Float32": return WorkbenchServiceFactory.DebuggerManager.language.LanguageIntellisenseSupport.GetShortTypeName(typeof(float));
case "System.IntPtr": return WorkbenchServiceFactory.DebuggerManager.language.LanguageIntellisenseSupport.GetShortTypeName(Type.GetType("System.Void*"));
2015-05-14 22:35:07 +03:00
default: return name;
}
else
switch (name)
{
case "System.Boolean": return "boolean";
case "System.Int32": return "integer";
case "System.Byte": return "byte";
case "System.Double": return "real";
case "System.String": return "string";
case "System.Char": return "char";
case "System.SByte": return "shortint";
case "System.Int16": return "smallint";
case "System.UInt16": return "word";
case "System.UInt32": return "longword";
case "System.Int64": return "int64";
case "System.UInt64": return "uint64";
case "System.Float32": return "single";
case "System.IntPtr": return "pointer";
default: return name;
}
}
public static object GetEnumValue(Value v)
{
Value val = v.GetMember("value__");
if (val != null && val.IsPrimitive)
return val.PrimitiveValue;
return null;
}
public static Value unbox(Value v)
{
return v.GetMember("m_value");
}
public static string MakeViewForCollection(Value v)
{
object cnt = v.GetMember("Count").PrimitiveValue;
return "Count = " + cnt.ToString();
}
public static Value MakeValue(object obj)
{
Value v = null;
if (!(obj is string))
{
v = Eval.CreateValue(WorkbenchServiceFactory.DebuggerManager.DebuggedProcess, obj);
v.SetPrimitiveValue(obj);
}
else
{
v = Eval.NewString(WorkbenchServiceFactory.DebuggerManager.DebuggedProcess, obj as string);
}
return v;
}
}
}