Skip to content

Commit 6ac9e8c

Browse files
authored
Merge pull request #1674 from EvilBeaver/feature/issue-1673-native-compile
Проброс bsl-процесса при native-компиляции.
2 parents dc2c920 + 59f99f1 commit 6ac9e8c

3 files changed

Lines changed: 129 additions & 8 deletions

File tree

src/OneScript.Native/Compiler/MethodCompiler.cs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,20 @@ protected override void VisitGlobalFunctionCall(CallNode node)
10921092
_statementBuildParts.Push(expression);
10931093
}
10941094

1095+
private static bool InjectedProcessNeeded(MethodInfo methodInfo)
1096+
{
1097+
if (methodInfo is ContextMethodInfo { InjectsProcess: true })
1098+
{
1099+
return true;
1100+
}
1101+
var p = methodInfo.GetParameters();
1102+
if (p.Length > 0 && p[0].ParameterType == typeof(IBslProcess))
1103+
{
1104+
return true;
1105+
}
1106+
return false;
1107+
}
1108+
10951109
protected override void VisitObjectProcedureCall(BslSyntaxNode node)
10961110
{
10971111
var target = _statementBuildParts.Pop();
@@ -1102,7 +1116,8 @@ protected override void VisitObjectProcedureCall(BslSyntaxNode node)
11021116
if (targetType.IsObjectValue())
11031117
{
11041118
var methodInfo = FindMethodOfType(node, targetType, name);
1105-
var args = PrepareCallArguments(call.ArgumentList, methodInfo.GetParameters(), methodInfo is ContextMethodInfo { InjectsProcess: true });
1119+
var injectProcess = InjectedProcessNeeded(methodInfo);
1120+
var args = PrepareCallArguments(call.ArgumentList, methodInfo.GetParameters(), injectProcess);
11061121

11071122
_blocks.Add(Expression.Call(target, methodInfo, args));
11081123
}
@@ -1168,8 +1183,8 @@ protected override void VisitObjectFunctionCall(BslSyntaxNode node)
11681183
$"Метод {targetType}.{name} не является функцией",
11691184
$"Method {targetType}.{name} is not a function"), ToCodePosition(node.Location));
11701185
}
1171-
1172-
var args = PrepareCallArguments(call.ArgumentList, methodInfo.GetParameters(), methodInfo is ContextMethodInfo { InjectsProcess: true });
1186+
1187+
var args = PrepareCallArguments(call.ArgumentList, methodInfo.GetParameters(), InjectedProcessNeeded(methodInfo));
11731188
_statementBuildParts.Push(Expression.Call(target, methodInfo, args));
11741189
}
11751190
else if (targetType.IsContext())
@@ -1266,7 +1281,7 @@ private Expression CreateMethodCall(CallNode node)
12661281
}
12671282

12681283
var symbol = Symbols.GetScope(binding.ScopeNumber).Methods[binding.MemberNumber];
1269-
var args = PrepareCallArguments(node.ArgumentList, symbol.Method.GetParameters(), symbol.Method is ContextMethodInfo { InjectsProcess: true });
1284+
var args = PrepareCallArguments(node.ArgumentList, symbol.Method.GetParameters(), InjectedProcessNeeded(symbol.Method));
12701285

12711286
var methodInfo = symbol.Method;
12721287
if (methodInfo is ContextMethodInfo contextMethod)
@@ -1418,8 +1433,8 @@ private List<Expression> PrepareCallArguments(BslSyntaxNode argList, ParameterIn
14181433
? ConvertToExpressionTree(passedArg.Children[0])
14191434
: null).ToArray();
14201435

1421-
var parametersToProcess = declaredParameters.Length;
14221436
var declStart = injectsProcess ? 1 : 0;
1437+
var parametersToProcess = declaredParameters.Length - declStart;
14231438
for (int i = 0, decl = declStart; i < parameters.Length; i++, decl++)
14241439
{
14251440
if (parametersToProcess == 0)

src/Tests/OneScript.Core.Tests/HelperClasses/TestContextClass.cs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ This Source Code Form is subject to the terms of the
55
at http://mozilla.org/MPL/2.0/.
66
----------------------------------------------------------*/
77

8-
using System.Collections.Generic;
98
using OneScript.Contexts;
9+
using OneScript.Execution;
1010
using OneScript.Types;
1111
using OneScript.Values;
1212
using ScriptEngine.Machine;
1313
using ScriptEngine.Machine.Contexts;
1414
using ScriptEngine.Types;
15+
using System.Collections.Generic;
1516

1617
namespace OneScript.Core.Tests
1718
{
@@ -60,7 +61,46 @@ public override void SetIndexedValue(IValue index, IValue val)
6061
_indexedValues[(BslValue)index] = (BslValue)val;
6162
}
6263

63-
[ScriptConstructor]
64+
#region IBslProcessTests
65+
66+
[ContextMethod("Процедура0")]
67+
public void Procedure0() { }
68+
69+
[ContextMethod("Процедура0СПроцессом")]
70+
public void Procedure0WithProcess(IBslProcess process) { }
71+
72+
[ContextMethod("Процедура1")]
73+
public void Procedure1(int intValue) { }
74+
75+
[ContextMethod("Процедура1СПроцессом")]
76+
public void Procedure1WithProcess(IBslProcess process, int intValue) { }
77+
78+
[ContextMethod("Процедура1СУмолчанием")]
79+
public void Procedure1WithDefault(int intValue = 0) { }
80+
81+
[ContextMethod("Процедура1СУмолчаниемСПроцессом")]
82+
public void Procedure1WithDefaultWithProcess(IBslProcess process, int intValue = 0) { }
83+
84+
[ContextMethod("Функция0")]
85+
public int Function0() { return 0; }
86+
87+
[ContextMethod("Функция0СПроцессом")]
88+
public int Function0WithProcess(IBslProcess process) { return 0; }
89+
90+
[ContextMethod("Функция1")]
91+
public int Function1(int intValue) { return intValue; }
92+
93+
[ContextMethod("Функция1СПроцессом")]
94+
public int Function1WithProcess(IBslProcess process, int intValue) { return intValue; }
95+
96+
[ContextMethod("Функция1СУмолчанием")]
97+
public int Function1WithDefault(int intValue = 0) { return intValue; }
98+
99+
[ContextMethod("Функция1СУмолчаниемСПроцессом")]
100+
public int Function1WithDefaultWithProcess(IBslProcess process, int intValue = 0) { return intValue; }
101+
#endregion
102+
103+
[ScriptConstructor]
64104
public static TestContextClass Constructor()
65105
{
66106
return new TestContextClass

src/Tests/OneScript.Core.Tests/NativeCompilerTest.cs

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,73 @@ public void Can_Call_Member_Procedures()
867867

868868
array.Should().HaveCount(2);
869869
}
870-
870+
871+
[Theory]
872+
[InlineData("Объект.Процедура0();")]
873+
[InlineData("Объект.Процедура0СПроцессом();")]
874+
[InlineData("Объект.Процедура1(1);")]
875+
[InlineData("Объект.Процедура1СПроцессом(1);")]
876+
[InlineData("Объект.Процедура1СУмолчанием();")]
877+
[InlineData("Объект.Процедура1СУмолчаниемСПроцессом();")]
878+
[InlineData("Объект.Процедура1СУмолчанием(1);")]
879+
[InlineData("Объект.Процедура1СУмолчаниемСПроцессом(1);")]
880+
public void Can_Call_Member_ProceduresWithBslProcess(string code)
881+
{
882+
var tm = new DefaultTypeManager();
883+
var testType = tm.RegisterClass(typeof(TestContextClass));
884+
885+
var block = new CompiledBlock(default);
886+
block.Parameters.Insert("Объект", new BslTypeValue(testType));
887+
block.CodeBlock = code;
888+
889+
var method = block.CreateDelegate<Func<TestContextClass, BslValue>>();
890+
var testValue = new TestContextClass();
891+
method(testValue);
892+
}
893+
894+
[Theory]
895+
[InlineData("Объект.Функция0()")]
896+
[InlineData("Объект.Функция0СПроцессом()")]
897+
[InlineData("Объект.Функция1(1)")]
898+
[InlineData("Объект.Функция1СПроцессом(1)")]
899+
[InlineData("Объект.Функция1СУмолчанием()")]
900+
[InlineData("Объект.Функция1СУмолчаниемСПроцессом()")]
901+
[InlineData("Объект.Функция1СУмолчанием(1)")]
902+
[InlineData("Объект.Функция1СУмолчаниемСПроцессом(1)")]
903+
public void Can_Call_Member_FunctionsWithBslProcess(string code)
904+
{
905+
var tm = new DefaultTypeManager();
906+
var testType = tm.RegisterClass(typeof(TestContextClass));
907+
908+
var block = new CompiledBlock(default);
909+
block.Parameters.Insert("Объект", new BslTypeValue(testType));
910+
block.CodeBlock = $"Результат = {code};";
911+
912+
var method = block.CreateDelegate<Func<TestContextClass, BslValue>>();
913+
var testValue = new TestContextClass();
914+
method(testValue);
915+
}
916+
917+
[Theory]
918+
[InlineData("Объект.Процедура0СПроцессом(1)")]
919+
[InlineData("Объект.Функция0СПроцессом(1)")]
920+
[InlineData("Объект.Функция1СУмолчаниемСПроцессом(1, 2)")]
921+
[InlineData("Объект.Процедура1СУмолчаниемСПроцессом(1, 2, 3);")]
922+
public void Cannot_Call_Member_Procedures_With_Wrong_Argument_Count(string code)
923+
{
924+
var tm = new DefaultTypeManager();
925+
var testType = tm.RegisterClass(typeof(TestContextClass));
926+
927+
var block = new CompiledBlock(default);
928+
block.Parameters.Insert("Объект", new BslTypeValue(testType));
929+
block.CodeBlock = code;
930+
931+
var runtimeException = Assert.ThrowsAny<RuntimeException>(() => {
932+
var method = block.CreateDelegate<Func<TestContextClass, BslValue>>();
933+
});
934+
Assert.Contains("Слишком много фактических параметров", runtimeException.Message);
935+
}
936+
871937
[Fact]
872938
public void Can_Call_Member_Procedures_On_Dynamics()
873939
{

0 commit comments

Comments
 (0)