Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

В рефлектор добавлен метод ИзвестныеТипы() #1368

Merged
merged 4 commits into from
Oct 19, 2023
Merged
4 changes: 4 additions & 0 deletions src/OneScript.Core/Types/ITypeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ This Source Code Form is subject to the terms of the
----------------------------------------------------------*/

using System;
using System.Collections.Generic;

namespace OneScript.Types
{
Expand All @@ -25,5 +26,8 @@ public interface ITypeManager

bool IsKnownType(Type type);
bool IsKnownType(string typeName);

List<TypeDescriptor> RegisteredTypes();

}
}
46 changes: 44 additions & 2 deletions src/OneScript.StandardLibrary/Reflector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This Source Code Form is subject to the terms of the
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using OneScript.Commons;
using OneScript.Contexts;
using OneScript.Exceptions;
using OneScript.Execution;
Expand All @@ -30,6 +31,13 @@ namespace OneScript.StandardLibrary
[ContextClass("Рефлектор","Reflector")]
public class ReflectorContext : AutoContext<ReflectorContext>
{
private readonly ITypeManager _typeManager;

private ReflectorContext(ITypeManager typeManager)
{
_typeManager = typeManager;
}

/// <summary>
/// Вызывает метод по его имени.
/// </summary>
Expand Down Expand Up @@ -478,10 +486,44 @@ public static Type ReflectContext(Type clrType)
.Build();
}

/// <summary>
/// Возвращает все известные типы
/// </summary>
/// <returns>
/// Соответствие из КлючИЗначение:
/// * Ключ - Тип - Тип
/// * Значение - Структура - Описание типа:
/// * Имя - Строка - Имя типа
/// * Примитивный - Булево - Тип является примитивным
/// * Пользовательский - Булево - Тип является пользовательским
///
/// </returns>
[ContextMethod("ИзвестныеТипы", "KnownTypes")]
public MapImpl KnownTypes()
{
var result = new MapImpl();

_typeManager.RegisteredTypes()
sfaqer marked this conversation as resolved.
Show resolved Hide resolved
.ToDictionary(descriptor => new BslTypeValue(descriptor), descriptor =>
{
var typeDefinition = new StructureImpl();
typeDefinition.Insert("Имя", BslStringValue.Create(descriptor.ToString()));
typeDefinition.Insert("Примитивный",
descriptor.ImplementingClass.IsSubclassOf(typeof(BslPrimitiveValue)) ? BslBooleanValue.True : BslBooleanValue.False);
typeDefinition.Insert("Пользовательский",
descriptor.ImplementingClass == typeof(AttachedScriptsFactory) ? BslBooleanValue.True : BslBooleanValue.False);

return typeDefinition;
})
.ForEach(value => result.Insert(value.Key, value.Value));

return result;
}

[ScriptConstructor]
public static IRuntimeContextInstance CreateNew()
public static IValue CreateNew(TypeActivationContext context)
sfaqer marked this conversation as resolved.
Show resolved Hide resolved
{
return new ReflectorContext();
return new ReflectorContext(context.TypeManager);
}
}
}
5 changes: 5 additions & 0 deletions src/ScriptEngine/Machine/DefaultTypeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ public bool IsKnownType(string typeName)
return _knownTypes.Any(x => x.Name.ToUpperInvariant() == nameToUpper);
}

public List<TypeDescriptor> RegisteredTypes()
{
return _knownTypes;
sfaqer marked this conversation as resolved.
Show resolved Hide resolved
}

public Type NewInstanceHandler
{
get
Expand Down
61 changes: 59 additions & 2 deletions tests/reflector.os
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
ВсеТесты.Добавить("ТестДолжен_ПроверитьРефлексиюДля_ЭтотОбъект");
ВсеТесты.Добавить("ТестДолжен_ПроверитьПустыеАннотации");
ВсеТесты.Добавить("ТестДолжен_ПроверитьПриватныеПоля");

ВсеТесты.Добавить("ТестДолжен_ПроверитьИзвестныеТипы");

Возврат ВсеТесты;
КонецФункции
Expand Down Expand Up @@ -215,7 +217,7 @@
ТаблицаМетодов = Рефлектор.ПолучитьТаблицуМетодов(Пример);

юТест.ПроверитьРавенство(Строка(ТипЗнч(ТаблицаМетодов)), "ТаблицаЗначений", "ТаблицаМетодов");
юТест.ПроверитьРавенство(6, ТаблицаМетодов.Количество(), "ТаблицаМетодов.Количество()");
юТест.ПроверитьРавенство(7, ТаблицаМетодов.Количество(), "ТаблицаМетодов.Количество()");

Метод0 = ТаблицаМетодов.Найти("ВызватьМетод", "Имя");
юТест.ПроверитьНеРавенство(Неопределено, Метод0, "Метод0");
Expand Down Expand Up @@ -667,4 +669,59 @@
юТест.ПроверитьНеравенство(0, ТаблицаМетодов.Количество());
юТест.ПроверитьНеравенство(0, ТаблицаСвойств.Количество());

КонецПроцедуры
КонецПроцедуры

Процедура ТестДолжен_ПроверитьИзвестныеТипы() Экспорт

ПолучитьОбъектДляПроверки("МойКлассныйТип");

Рефлектор = Новый Рефлектор;

ИзвестныеТипы = Рефлектор.ИзвестныеТипы();

юТест.ПроверитьТип(ИзвестныеТипы, "Соответствие");
юТест.ПроверитьНеРавенство(ИзвестныеТипы.Количество(), 0);

Для Каждого ТипИОписание Из ИзвестныеТипы Цикл

юТест.ПроверитьТип(ТипИОписание.Ключ, "Тип");
юТест.ПроверитьЗаполненность(ТипИОписание.Ключ);

ОписаниеТипа = ТипИОписание.Значение;

юТест.ПроверитьТип(ОписаниеТипа, "Структура");

юТест.ПроверитьИстину(ОписаниеТипа.Свойство("Имя"));
юТест.ПроверитьИстину(ОписаниеТипа.Свойство("Примитивный"));
юТест.ПроверитьИстину(ОписаниеТипа.Свойство("Пользовательский"));

юТест.ПроверитьТип(ОписаниеТипа.Имя, "Строка");
юТест.ПроверитьТип(ОписаниеТипа.Примитивный, "Булево");
юТест.ПроверитьТип(ОписаниеТипа.Пользовательский, "Булево");

юТест.ПроверитьЗаполненность(ОписаниеТипа.Имя);

КонецЦикла;

ОписаниеТипаЧисло = ИзвестныеТипы.Получить(Тип("Число"));

юТест.ПроверитьЗаполненность(ОписаниеТипаЧисло);
юТест.ПроверитьТип(ОписаниеТипаЧисло, "Структура");
юТест.ПроверитьИстину(ОписаниеТипаЧисло.Примитивный);
юТест.ПроверитьЛожь(ОписаниеТипаЧисло.Пользовательский);

ОписаниеТипаМассив = ИзвестныеТипы.Получить(Тип("Массив"));

юТест.ПроверитьЗаполненность(ОписаниеТипаМассив);
юТест.ПроверитьТип(ОписаниеТипаМассив, "Структура");
юТест.ПроверитьЛожь(ОписаниеТипаМассив.Примитивный);
юТест.ПроверитьЛожь(ОписаниеТипаМассив.Пользовательский);

ОписаниеТипаМойКлассныйТип = ИзвестныеТипы.Получить(Тип("МойКлассныйТип"));

юТест.ПроверитьЗаполненность(ОписаниеТипаМойКлассныйТип);
юТест.ПроверитьТип(ОписаниеТипаМойКлассныйТип, "Структура");
юТест.ПроверитьЛожь(ОписаниеТипаМойКлассныйТип.Примитивный);
юТест.ПроверитьИстину(ОписаниеТипаМойКлассныйТип.Пользовательский);

КонецПроцедуры