/
EvilBeaver
/
OneScript
Обзор
Документация
Войти
/
EvilBeaver
/
OneScript
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
v2.0.3-alpha
src/OneScript.Native/Runtime/DynamicOperations.cs
161 строка
6 KB
Andrey Ovsiankin
Первый подход к информации об исключениях
28 апр 2021, 14:40
28 апр 2021, 14:40
897a086
Код
Авторство
О чём код?
/*---------------------------------------------------------- This Source Code Form is subject to the terms of the Mozilla Public License, v.2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. ----------------------------------------------------------*/ using System; using System.Linq; using OneScript.Commons; using OneScript.DependencyInjection; using OneScript.Language; using OneScript.Localization; using OneScript.Types; using OneScript.Values; using ScriptEngine.Machine; namespace OneScript.Native.Runtime { internal static class DynamicOperations { public static BslValue Add(BslValue left, BslValue right) { if (left is BslStringValue str) return BslStringValue.Create(str + right); if (left is BslDateValue bslDate && right is BslNumericValue num) { return BslDateValue.Create(bslDate - (decimal) num); } dynamic dLeft = left; dynamic dRight = right; return dLeft + dRight; } public static BslValue Subtract(BslValue left, BslValue right) { if (left is BslNumericValue num) { var result = num - ToNumber(right); return BslNumericValue.Create(result); } else if (left is BslDateValue date) { switch (right) { case BslNumericValue numRight: { var result = date - numRight; return BslDateValue.Create(result); } case BslDateValue dateRight: { var result = date - dateRight; return BslNumericValue.Create(result); } } } else { dynamic dLeft = left; dynamic dRight = right; return dLeft - dRight; } throw BslExceptions.ConvertToNumberException(); } public static bool ToBoolean(BslValue value) { return value switch { BslNumericValue n => (bool)n, BslBooleanValue b => (bool)b, _ => (bool)(dynamic)value }; } public static decimal ToNumber(BslValue value) { return value switch { BslNumericValue n => (decimal)n, BslBooleanValue b => (decimal)b, _ => (decimal)(dynamic)value }; } public static DateTime ToDate(BslValue value) { return value switch { BslDateValue n => (DateTime)n, _ => (DateTime)(dynamic)value }; } public static BslValue WrapClrObjectToValue(object value) { return value switch { null => BslUndefinedValue.Instance, string s => BslStringValue.Create(s), decimal d => BslNumericValue.Create(d), int n => BslNumericValue.Create(n), long l => BslNumericValue.Create(l), double dbl => BslNumericValue.Create((decimal) dbl), bool boolean => BslBooleanValue.Create(boolean), DateTime date => BslDateValue.Create(date), _ => throw new TypeConversionException(new BilingualString( $"Невозможно преобразовать {value.GetType()} в тип {nameof(BslValue)}", $"Can't Convert {value.GetType()} to {nameof(BslValue)}")) }; } public static BslValue ConstructorCall(ITypeManager typeManager, IServiceContainer services, string typeName, BslValue[] args) { var type = typeManager.GetTypeByName(typeName); var factory = typeManager.GetFactoryFor(type); var context = new TypeActivationContext { TypeManager = typeManager, Services = services, TypeName = type.Name }; return (BslValue) factory.Activate(context, args.Cast<IValue>().ToArray()); } // TODO: Сделать прямой маппинг на статические фабрики-методы, а не через Factory.Activate public static T StrictConstructorCall<T>(ITypeManager typeManager, IServiceContainer services, string typeName, BslValue[] args) where T : BslValue { return (T) ConstructorCall(typeManager, services, typeName, args); } public static ExceptionInfoClass GetExceptionInfo(Exception e) { if (e is ScriptException s) return new ExceptionInfoClass(s); var wrapper = new ExternalSystemException(e); return new ExceptionInfoClass(wrapper); } public static TypeDescriptor GetTypeByName(ITypeManager manager, string name) { var firstTry = manager.GetTypeByName(name); // костыль подмены типа для Тип("ИнформацияОбОшибке") if (firstTry.Name == ExceptionInfoClass.LanguageType.Name) { return ExceptionInfoClass.LanguageType; } return firstTry; } } }