From 806dd26567d31949681decbd19a946c4692d9150 Mon Sep 17 00:00:00 2001 From: sfaqer Date: Wed, 18 Oct 2023 17:29:41 +1000 Subject: [PATCH] =?UTF-8?q?=D0=92=20=D1=80=D0=B5=D1=84=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=82=D0=BE=D1=80=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=20=D0=98=D0=B7=D0=B2?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=BD=D1=8B=D0=B5=D0=A2=D0=B8=D0=BF=D1=8B()?= =?UTF-8?q?=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BC?= =?UTF-8?q?=D0=B5=D1=82=D0=BE=D0=B4=20=D0=BA=D0=BE=D1=82=D0=BE=D1=80=D1=8B?= =?UTF-8?q?=D0=B9=20=D0=B2=D0=BE=D0=B7=D0=B2=D1=80=D0=B0=D1=89=D0=B0=D0=B5?= =?UTF-8?q?=D1=82=20=D0=B2=D1=81=D0=B5=20=D0=B7=D0=B0=D1=80=D0=B5=D0=B3?= =?UTF-8?q?=D0=B8=D1=81=D1=82=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D0=BD=D1=8B=D0=B5=20=D1=82=D0=B8=D0=BF=D1=8B=20=D0=B2=20=D0=B2?= =?UTF-8?q?=D0=B8=D0=B4=D0=B5=20=D0=A2=D0=B0=D0=B1=D0=BB=D0=B8=D1=86=D0=B0?= =?UTF-8?q?=D0=97=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8=D0=B9<=D0=98=D0=BC?= =?UTF-8?q?=D1=8F,=20=D0=97=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8=D0=B5,=20?= =?UTF-8?q?=D0=9F=D1=80=D0=B8=D0=BC=D0=B8=D1=82=D0=B8=D0=B2=D0=BD=D1=8B?= =?UTF-8?q?=D0=B9,=20=D0=9F=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D1=82=D0=B5=D0=BB=D1=8C=D1=81=D0=BA=D0=B8=D0=B9,=20=D0=9A?= =?UTF-8?q?=D0=BE=D0=BB=D0=BB=D0=B5=D0=BA=D1=86=D0=B8=D1=8F>?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Library/Reflector.cs | 46 +++++ src/ScriptEngine/Machine/TypeManager.cs | 11 ++ tests/reflector.os | 162 +++++++++++++++++- 3 files changed, 217 insertions(+), 2 deletions(-) diff --git a/src/ScriptEngine.HostedScript/Library/Reflector.cs b/src/ScriptEngine.HostedScript/Library/Reflector.cs index 68264ecbb..b94eeb85c 100644 --- a/src/ScriptEngine.HostedScript/Library/Reflector.cs +++ b/src/ScriptEngine.HostedScript/Library/Reflector.cs @@ -485,6 +485,52 @@ public static Type ReflectContext(Type clrType) .Build(); } + /// + /// Возвращает все известные типы + /// + /// Структура - Условия поиска. Ключ - имя колонки, значение - искомое значение + /// + /// ТаблицаЗначений: + /// * Имя - Строка - Имя типа + /// * Значение - Тип - Тип + /// * Примитивный - Булево - Это примитивный тип + /// * Пользовательский - Булево - Это пользовательский типа + /// * Коллекция - Булево - Это коллекция + /// + [ContextMethod("ИзвестныеТипы", "KnownTypes")] + public ValueTable.ValueTable KnownTypes(StructureImpl filter = default) + { + var result = new ValueTable.ValueTable(); + + var nameColumn = result.Columns.Add("Имя", TypeDescription.StringType()); + var valueColumn = result.Columns.Add("Значение", new TypeDescription(new List() { new TypeTypeValue(CommonTypes.Type) })); + var primitiveColumn = result.Columns.Add("Примитивный", TypeDescription.BooleanType()); + var userColumn = result.Columns.Add("Пользовательский", TypeDescription.BooleanType()); + var collectionColumn = result.Columns.Add("Коллекция", TypeDescription.BooleanType()); + + TypeManager.RegisteredTypes().ForEach(descriptor => + { + var implementingClass = TypeManager.GetImplementingClass(descriptor.ID); + + var row = result.Add(); + + row.Set(nameColumn, ValueFactory.Create(descriptor.ToString())); + row.Set(valueColumn, new TypeTypeValue(descriptor)); + row.Set(primitiveColumn, ValueFactory.Create(implementingClass == typeof(DataType))); + row.Set(userColumn, ValueFactory.Create(implementingClass == typeof(AttachedScriptsFactory))); + row.Set(collectionColumn, ValueFactory.Create( + implementingClass.GetInterface(nameof(ICollectionContext)) != null) + ); + }); + + if (filter != default) + { + result = result.Copy(filter); + } + + return result; + } + [ScriptConstructor] public static IRuntimeContextInstance CreateNew() { diff --git a/src/ScriptEngine/Machine/TypeManager.cs b/src/ScriptEngine/Machine/TypeManager.cs index 2c9521b04..f0693e1a6 100644 --- a/src/ScriptEngine/Machine/TypeManager.cs +++ b/src/ScriptEngine/Machine/TypeManager.cs @@ -24,6 +24,7 @@ public interface ITypeManager bool IsKnownType(Type type); bool IsKnownType(string typeName); Type NewInstanceHandler { get; set; } + IReadOnlyList RegisteredTypes(); } class StandartTypeManager : ITypeManager @@ -206,6 +207,11 @@ public Type NewInstanceHandler } } + public IReadOnlyList RegisteredTypes() + { + return _knownTypes.Select(type => type.Descriptor).ToList(); + } + public TypeDescriptor GetTypeDescriptorFor(IValue typeTypeValue) { if (typeTypeValue.DataType != DataType.Type) @@ -323,6 +329,11 @@ public static TypeFactory GetFactoryFor(string typeName) return factory; } + + public static IReadOnlyList RegisteredTypes() + { + return _instance.RegisteredTypes(); + } } } diff --git a/tests/reflector.os b/tests/reflector.os index c36ae18e2..6d77addab 100644 --- a/tests/reflector.os +++ b/tests/reflector.os @@ -42,6 +42,11 @@ ВсеТесты.Добавить("ТестДолжен_ПроверитьПустыеАннотации"); ВсеТесты.Добавить("ТестДолжен_ПроверитьПриватныеПоля"); + ВсеТесты.Добавить("ТестДолжен_ПроверитьИзвестныеТипы"); + ВсеТесты.Добавить("ТестДолжен_ПроверитьИзвестныеТипы_СОтборомКоллекция"); + ВсеТесты.Добавить("ТестДолжен_ПроверитьИзвестныеТипы_СОтборомПримитивный"); + ВсеТесты.Добавить("ТестДолжен_ПроверитьИзвестныеТипы_СОтборомПользовательский"); + Возврат ВсеТесты; КонецФункции @@ -215,7 +220,7 @@ ТаблицаМетодов = Рефлектор.ПолучитьТаблицуМетодов(Пример); юТест.ПроверитьРавенство(Строка(ТипЗнч(ТаблицаМетодов)), "ТаблицаЗначений", "ТаблицаМетодов"); - юТест.ПроверитьРавенство(6, ТаблицаМетодов.Количество(), "ТаблицаМетодов.Количество()"); + юТест.ПроверитьРавенство(7, ТаблицаМетодов.Количество(), "ТаблицаМетодов.Количество()"); Метод0 = ТаблицаМетодов.Найти("ВызватьМетод", "Имя"); юТест.ПроверитьНеРавенство(Неопределено, Метод0, "Метод0"); @@ -678,4 +683,157 @@ юТест.ПроверитьНеравенство(0, ТаблицаМетодов.Количество()); юТест.ПроверитьНеравенство(0, ТаблицаСвойств.Количество()); -КонецПроцедуры \ No newline at end of file +КонецПроцедуры + +Процедура ТестДолжен_ПроверитьИзвестныеТипы() Экспорт + + ПолучитьОбъектДляПроверки("МойКлассныйТип"); + + Рефлектор = Новый Рефлектор; + + ИзвестныеТипы = Рефлектор.ИзвестныеТипы(); + + ПроверитьТипИзвестныхТипов(ИзвестныеТипы); + + Для Каждого ИзвестныйТип Из ИзвестныеТипы Цикл + ПроверитьСтрокуИзвестныхТипов(ИзвестныйТип); + КонецЦикла; + + ОписаниеТипаЧисло = ИзвестныеТипы.Найти(Тип("Число")); + + юТест.ПроверитьЗаполненность(ОписаниеТипаЧисло); + юТест.ПроверитьТип(ОписаниеТипаЧисло, "СтрокаТаблицыЗначений"); + юТест.ПроверитьИстину(ОписаниеТипаЧисло.Примитивный); + юТест.ПроверитьЛожь(ОписаниеТипаЧисло.Пользовательский); + юТест.ПроверитьЛожь(ОписаниеТипаЧисло.Коллекция); + + ОписаниеТипаМассив = ИзвестныеТипы.Найти(Тип("Массив")); + + юТест.ПроверитьЗаполненность(ОписаниеТипаМассив); + юТест.ПроверитьТип(ОписаниеТипаМассив, "СтрокаТаблицыЗначений"); + юТест.ПроверитьЛожь(ОписаниеТипаМассив.Примитивный); + юТест.ПроверитьЛожь(ОписаниеТипаМассив.Пользовательский); + юТест.ПроверитьИстину(ОписаниеТипаМассив.Коллекция); + + ОписаниеТипаМойКлассныйТип = ИзвестныеТипы.Найти(Тип("МойКлассныйТип")); + + юТест.ПроверитьЗаполненность(ОписаниеТипаМойКлассныйТип); + юТест.ПроверитьТип(ОписаниеТипаМойКлассныйТип, "СтрокаТаблицыЗначений"); + юТест.ПроверитьЛожь(ОписаниеТипаМойКлассныйТип.Примитивный); + юТест.ПроверитьИстину(ОписаниеТипаМойКлассныйТип.Пользовательский); + юТест.ПроверитьЛожь(ОписаниеТипаМойКлассныйТип.Коллекция); + +КонецПроцедуры + +Процедура ТестДолжен_ПроверитьИзвестныеТипы_СОтборомКоллекция() Экспорт + + ПолучитьОбъектДляПроверки("МойКлассныйТип"); + + Рефлектор = Новый Рефлектор; + + Отбор = Новый Структура("Коллекция", Истина); + + ИзвестныеТипы = Рефлектор.ИзвестныеТипы(Отбор); + + ПроверитьТипИзвестныхТипов(ИзвестныеТипы); + + Для Каждого ИзвестныйТип Из ИзвестныеТипы Цикл + ПроверитьСтрокуИзвестныхТипов(ИзвестныйТип); + + юТест.ПроверитьИстину(ИзвестныйТип.Коллекция); + юТест.ПроверитьЛожь(ИзвестныйТип.Примитивный); + юТест.ПроверитьЛожь(ИзвестныйТип.Пользовательский); + + КонецЦикла; + + ОписаниеТипаМассив = ИзвестныеТипы.Найти(Тип("Массив")); + + юТест.ПроверитьЗаполненность(ОписаниеТипаМассив); + юТест.ПроверитьТип(ОписаниеТипаМассив, "СтрокаТаблицыЗначений"); + +КонецПроцедуры + +Процедура ТестДолжен_ПроверитьИзвестныеТипы_СОтборомПримитивный() Экспорт + + ПолучитьОбъектДляПроверки("МойКлассныйТип"); + + Рефлектор = Новый Рефлектор; + + Отбор = Новый Структура("Примитивный", Истина); + + ИзвестныеТипы = Рефлектор.ИзвестныеТипы(Отбор); + + ПроверитьТипИзвестныхТипов(ИзвестныеТипы); + + Для Каждого ИзвестныйТип Из ИзвестныеТипы Цикл + + ПроверитьСтрокуИзвестныхТипов(ИзвестныйТип); + + юТест.ПроверитьЛожь(ИзвестныйТип.Коллекция); + юТест.ПроверитьИстину(ИзвестныйТип.Примитивный); + юТест.ПроверитьЛожь(ИзвестныйТип.Пользовательский); + + КонецЦикла; + + ОписаниеТипаЧисло = ИзвестныеТипы.Найти(Тип("Число")); + + юТест.ПроверитьЗаполненность(ОписаниеТипаЧисло); + юТест.ПроверитьТип(ОписаниеТипаЧисло, "СтрокаТаблицыЗначений"); + +КонецПроцедуры + +Процедура ТестДолжен_ПроверитьИзвестныеТипы_СОтборомПользовательский() Экспорт + + ПолучитьОбъектДляПроверки("МойКлассныйТип"); + + Рефлектор = Новый Рефлектор; + + Отбор = Новый Структура("Пользовательский", Истина); + + ИзвестныеТипы = Рефлектор.ИзвестныеТипы(Отбор); + + ПроверитьТипИзвестныхТипов(ИзвестныеТипы); + + Для Каждого ИзвестныйТип Из ИзвестныеТипы Цикл + + ПроверитьСтрокуИзвестныхТипов(ИзвестныйТип); + + юТест.ПроверитьЛожь(ИзвестныйТип.Коллекция); + юТест.ПроверитьЛожь(ИзвестныйТип.Примитивный); + юТест.ПроверитьИстину(ИзвестныйТип.Пользовательский); + + КонецЦикла; + + ОписаниеТипаМойКлассныйТип = ИзвестныеТипы.Найти(Тип("МойКлассныйТип")); + + юТест.ПроверитьЗаполненность(ОписаниеТипаМойКлассныйТип); + юТест.ПроверитьТип(ОписаниеТипаМойКлассныйТип, "СтрокаТаблицыЗначений"); + +КонецПроцедуры + +Процедура ПроверитьТипИзвестныхТипов(ИзвестныеТипы) + + юТест.ПроверитьТип(ИзвестныеТипы, "ТаблицаЗначений"); + юТест.ПроверитьНеРавенство(ИзвестныеТипы.Количество(), 0); + + юТест.ПроверитьРавенство(ИзвестныеТипы.Колонки.Количество(), 5); + юТест.ПроверитьЗаполненность(ИзвестныеТипы.Колонки.Найти("Имя")); + юТест.ПроверитьЗаполненность(ИзвестныеТипы.Колонки.Найти("Значение")); + юТест.ПроверитьЗаполненность(ИзвестныеТипы.Колонки.Найти("Примитивный")); + юТест.ПроверитьЗаполненность(ИзвестныеТипы.Колонки.Найти("Пользовательский")); + юТест.ПроверитьЗаполненность(ИзвестныеТипы.Колонки.Найти("Коллекция")); + +КонецПроцедуры + +Процедура ПроверитьСтрокуИзвестныхТипов(ИзвестныйТип) + + юТест.ПроверитьТип(ИзвестныйТип.Имя, "Строка"); + юТест.ПроверитьТип(ИзвестныйТип.Значение, "Тип"); + юТест.ПроверитьТип(ИзвестныйТип.Примитивный, "Булево"); + юТест.ПроверитьТип(ИзвестныйТип.Пользовательский, "Булево"); + юТест.ПроверитьТип(ИзвестныйТип.Коллекция, "Булево"); + + юТест.ПроверитьЗаполненность(ИзвестныйТип.Имя); + юТест.ПроверитьЗаполненность(ИзвестныйТип.Значение); + +КонецПроцедуры