Skip to content

Commit ecd6164

Browse files
committed
fix#1739: параметры конструктора из массива +тесты
1 parent 1a9b09d commit ecd6164

3 files changed

Lines changed: 55 additions & 5 deletions

File tree

‎src/OneScript.Native/Compiler/ExpressionHelpers.cs‎

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -520,16 +520,30 @@ public static Expression CreateAssignmentSource(Expression source, Type targetTy
520520
$"Conversion from type {source.Type} into {targetType} is not supported"));
521521
}
522522

523+
private static Expression ArgsFromArray(Expression[] args)
524+
{
525+
if (args.Length == 0)
526+
return Expression.NewArrayInit(typeof(IValue));
527+
528+
var arg1 = args[0];
529+
var typecheck = Expression.TypeIs(arg1, typeof(IValueArray));
530+
531+
var method = OperationsCache.GetOrAdd(typeof(Enumerable), nameof(Enumerable.ToArray)).MakeGenericMethod([typeof(IValue)]);
532+
var array = Expression.Call(method, Expression.Convert(arg1, typeof(IEnumerable<IValue>)));
533+
534+
return Expression.Condition(typecheck, array, Expression.NewArrayInit(typeof(IValue)));
535+
}
536+
523537
public static Expression ConstructorCall(ITypeManager typeManager, Expression services, Expression type,
524538
Expression process,
525539
Expression[] argsArray)
526540
{
527541
var method = OperationsCache.GetOrAdd(
528542
typeof(DynamicOperations),
529-
nameof(DynamicOperations.ConstructorCall));
530-
531-
var arrayOfArgs = Expression.NewArrayInit(typeof(BslValue), argsArray.Select(ConvertToBslValue));
532-
543+
nameof(DynamicOperations.DynamicConstructorCall));
544+
545+
var arrayOfArgs = ArgsFromArray(argsArray);
546+
533547
return Expression.Call(method,
534548
Expression.Constant(typeManager),
535549
services,

‎src/OneScript.Native/Runtime/DynamicOperations.cs‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ public static BslValue WrapClrObjectToValue(object value)
113113
};
114114
}
115115

116-
public static BslValue ConstructorCall(ITypeManager typeManager, IServiceContainer services, string typeName, IBslProcess process, BslValue[] args)
116+
public static BslValue ConstructorCall(ITypeManager typeManager, IServiceContainer services,
117+
string typeName, IBslProcess process, BslValue[] args)
117118
{
118119
var type = typeManager.GetTypeByName(typeName);
119120
var factory = typeManager.GetFactoryFor(type);
@@ -128,6 +129,22 @@ public static BslValue ConstructorCall(ITypeManager typeManager, IServiceContain
128129
return (BslValue) factory.Activate(context, args.Cast<IValue>().ToArray());
129130
}
130131

132+
public static BslValue DynamicConstructorCall(ITypeManager typeManager, IServiceContainer services,
133+
string typeName, IBslProcess process, IValue[] args)
134+
{
135+
var type = typeManager.GetTypeByName(typeName);
136+
var factory = typeManager.GetFactoryFor(type);
137+
var context = new TypeActivationContext
138+
{
139+
TypeManager = typeManager,
140+
Services = services,
141+
TypeName = type.Name,
142+
CurrentProcess = process
143+
};
144+
145+
return (BslValue)factory.Activate(context, args);
146+
}
147+
131148
// TODO: Сделать прямой маппинг на статические фабрики-методы, а не через Factory.Activate
132149
public static T StrictConstructorCall<T>(ITypeManager typeManager, IServiceContainer services,
133150
string typeName, IBslProcess process, BslValue[] args)

‎tests/native-module.os‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтениеЗаписьПоИндексу");
1414
//FIXME #1531
1515
//ВсеТесты.Добавить("ТестДолжен_ПроверитьДелегат");
16+
ВсеТесты.Добавить("ТестДолжен_ПроверитьДинамическийКонструктор");
1617

1718
Возврат ВсеТесты;
1819

@@ -53,3 +54,21 @@
5354
//юТест.ПроверитьРавенство("Привет", Результат);
5455

5556
КонецПроцедуры
57+
58+
Процедура ТестДолжен_ПроверитьДинамическийКонструктор() Экспорт
59+
Массив = Новый("Массив");
60+
юТест.ПроверитьРавенство(0, Массив.Количество(), "Без параметров");
61+
62+
МассивПараметров = Новый Массив();
63+
Массив = Новый("Массив", МассивПараметров);
64+
юТест.ПроверитьРавенство(0, Массив.Количество(), "С пустым массивом параметров");
65+
66+
МассивПараметров.Добавить(4);
67+
Массив = Новый("Массив", МассивПараметров);
68+
юТест.ПроверитьРавенство(4, Массив.Количество(), "С параметром в массиве");
69+
70+
МассивПараметров[0] = 5;
71+
ФиксированныйМассивПараметров = Новый ФиксированныйМассив(МассивПараметров);
72+
Массив = Новый("Массив", ФиксированныйМассивПараметров);
73+
юТест.ПроверитьРавенство(5, Массив.Количество(), "С параметром в фиксированном массиве");
74+
КонецПроцедуры

0 commit comments

Comments
 (0)