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); + юТест.ПроверитьЗаполненность(ИзвестныеТипы.Колонки.Найти("Имя")); + юТест.ПроверитьЗаполненность(ИзвестныеТипы.Колонки.Найти("Значение")); + юТест.ПроверитьЗаполненность(ИзвестныеТипы.Колонки.Найти("Примитивный")); + юТест.ПроверитьЗаполненность(ИзвестныеТипы.Колонки.Найти("Пользовательский")); + юТест.ПроверитьЗаполненность(ИзвестныеТипы.Колонки.Найти("Коллекция")); + +КонецПроцедуры + +Процедура ПроверитьСтрокуИзвестныхТипов(ИзвестныйТип) + + юТест.ПроверитьТип(ИзвестныйТип.Имя, "Строка"); + юТест.ПроверитьТип(ИзвестныйТип.Значение, "Тип"); + юТест.ПроверитьТип(ИзвестныйТип.Примитивный, "Булево"); + юТест.ПроверитьТип(ИзвестныйТип.Пользовательский, "Булево"); + юТест.ПроверитьТип(ИзвестныйТип.Коллекция, "Булево"); + + юТест.ПроверитьЗаполненность(ИзвестныйТип.Имя); + юТест.ПроверитьЗаполненность(ИзвестныйТип.Значение); + +КонецПроцедуры