Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions src/OneScript.Native/Compiler/MethodCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,20 @@ protected override void VisitGlobalFunctionCall(CallNode node)
_statementBuildParts.Push(expression);
}

private static bool InjectedProcessNeeded(MethodInfo methodInfo)
{
if (methodInfo is ContextMethodInfo { InjectsProcess: true })
{
return true;
}
var p = methodInfo.GetParameters();
if (p.Length > 0 && p[0].ParameterType == typeof(IBslProcess))
{
return true;
}
return false;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

protected override void VisitObjectProcedureCall(BslSyntaxNode node)
{
var target = _statementBuildParts.Pop();
Expand All @@ -1102,7 +1116,8 @@ protected override void VisitObjectProcedureCall(BslSyntaxNode node)
if (targetType.IsObjectValue())
{
var methodInfo = FindMethodOfType(node, targetType, name);
var args = PrepareCallArguments(call.ArgumentList, methodInfo.GetParameters(), methodInfo is ContextMethodInfo { InjectsProcess: true });
var injectProcess = InjectedProcessNeeded(methodInfo);
var args = PrepareCallArguments(call.ArgumentList, methodInfo.GetParameters(), injectProcess);

_blocks.Add(Expression.Call(target, methodInfo, args));
}
Expand Down Expand Up @@ -1168,8 +1183,8 @@ protected override void VisitObjectFunctionCall(BslSyntaxNode node)
$"Метод {targetType}.{name} не является функцией",
$"Method {targetType}.{name} is not a function"), ToCodePosition(node.Location));
}
var args = PrepareCallArguments(call.ArgumentList, methodInfo.GetParameters(), methodInfo is ContextMethodInfo { InjectsProcess: true });

var args = PrepareCallArguments(call.ArgumentList, methodInfo.GetParameters(), InjectedProcessNeeded(methodInfo));
_statementBuildParts.Push(Expression.Call(target, methodInfo, args));
}
else if (targetType.IsContext())
Expand Down Expand Up @@ -1266,7 +1281,7 @@ private Expression CreateMethodCall(CallNode node)
}

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

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

var parametersToProcess = declaredParameters.Length;
var declStart = injectsProcess ? 1 : 0;
var parametersToProcess = declaredParameters.Length - declStart;
for (int i = 0, decl = declStart; i < parameters.Length; i++, decl++)
{
if (parametersToProcess == 0)
Expand Down
44 changes: 42 additions & 2 deletions src/Tests/OneScript.Core.Tests/HelperClasses/TestContextClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ This Source Code Form is subject to the terms of the
at http://mozilla.org/MPL/2.0/.
----------------------------------------------------------*/

using System.Collections.Generic;
using OneScript.Contexts;
using OneScript.Execution;
using OneScript.Types;
using OneScript.Values;
using ScriptEngine.Machine;
using ScriptEngine.Machine.Contexts;
using ScriptEngine.Types;
using System.Collections.Generic;

namespace OneScript.Core.Tests
{
Expand Down Expand Up @@ -60,7 +61,46 @@ public override void SetIndexedValue(IValue index, IValue val)
_indexedValues[(BslValue)index] = (BslValue)val;
}

[ScriptConstructor]
#region IBslProcessTests

[ContextMethod("Процедура0")]
public void Procedure0() { }

[ContextMethod("Процедура0СПроцессом")]
public void Procedure0WithProcess(IBslProcess process) { }

[ContextMethod("Процедура1")]
public void Procedure1(int intValue) { }

[ContextMethod("Процедура1СПроцессом")]
public void Procedure1WithProcess(IBslProcess process, int intValue) { }

[ContextMethod("Процедура1СУмолчанием")]
public void Procedure1WithDefault(int intValue = 0) { }

[ContextMethod("Процедура1СУмолчаниемСПроцессом")]
public void Procedure1WithDefaultWithProcess(IBslProcess process, int intValue = 0) { }

[ContextMethod("Функция0")]
public int Function0() { return 0; }

[ContextMethod("Функция0СПроцессом")]
public int Function0WithProcess(IBslProcess process) { return 0; }

[ContextMethod("Функция1")]
public int Function1(int intValue) { return intValue; }

[ContextMethod("Функция1СПроцессом")]
public int Function1WithProcess(IBslProcess process, int intValue) { return intValue; }

[ContextMethod("Функция1СУмолчанием")]
public int Function1WithDefault(int intValue = 0) { return intValue; }

[ContextMethod("Функция1СУмолчаниемСПроцессом")]
public int Function1WithDefaultWithProcess(IBslProcess process, int intValue = 0) { return intValue; }
#endregion

[ScriptConstructor]
public static TestContextClass Constructor()
{
return new TestContextClass
Expand Down
68 changes: 67 additions & 1 deletion src/Tests/OneScript.Core.Tests/NativeCompilerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,73 @@ public void Can_Call_Member_Procedures()

array.Should().HaveCount(2);
}


[Theory]
[InlineData("Объект.Процедура0();")]
[InlineData("Объект.Процедура0СПроцессом();")]
[InlineData("Объект.Процедура1(1);")]
[InlineData("Объект.Процедура1СПроцессом(1);")]
[InlineData("Объект.Процедура1СУмолчанием();")]
[InlineData("Объект.Процедура1СУмолчаниемСПроцессом();")]
[InlineData("Объект.Процедура1СУмолчанием(1);")]
[InlineData("Объект.Процедура1СУмолчаниемСПроцессом(1);")]
public void Can_Call_Member_ProceduresWithBslProcess(string code)
{
var tm = new DefaultTypeManager();
var testType = tm.RegisterClass(typeof(TestContextClass));

var block = new CompiledBlock(default);
block.Parameters.Insert("Объект", new BslTypeValue(testType));
block.CodeBlock = code;

var method = block.CreateDelegate<Func<TestContextClass, BslValue>>();
var testValue = new TestContextClass();
method(testValue);
}

[Theory]
[InlineData("Объект.Функция0()")]
[InlineData("Объект.Функция0СПроцессом()")]
[InlineData("Объект.Функция1(1)")]
[InlineData("Объект.Функция1СПроцессом(1)")]
[InlineData("Объект.Функция1СУмолчанием()")]
[InlineData("Объект.Функция1СУмолчаниемСПроцессом()")]
[InlineData("Объект.Функция1СУмолчанием(1)")]
[InlineData("Объект.Функция1СУмолчаниемСПроцессом(1)")]
public void Can_Call_Member_FunctionsWithBslProcess(string code)
{
var tm = new DefaultTypeManager();
var testType = tm.RegisterClass(typeof(TestContextClass));

var block = new CompiledBlock(default);
block.Parameters.Insert("Объект", new BslTypeValue(testType));
block.CodeBlock = $"Результат = {code};";

var method = block.CreateDelegate<Func<TestContextClass, BslValue>>();
var testValue = new TestContextClass();
method(testValue);
}

[Theory]
[InlineData("Объект.Процедура0СПроцессом(1)")]
[InlineData("Объект.Функция0СПроцессом(1)")]
[InlineData("Объект.Функция1СУмолчаниемСПроцессом(1, 2)")]
[InlineData("Объект.Процедура1СУмолчаниемСПроцессом(1, 2, 3);")]
public void Cannot_Call_Member_Procedures_With_Wrong_Argument_Count(string code)
{
var tm = new DefaultTypeManager();
var testType = tm.RegisterClass(typeof(TestContextClass));

var block = new CompiledBlock(default);
block.Parameters.Insert("Объект", new BslTypeValue(testType));
block.CodeBlock = code;

var runtimeException = Assert.ThrowsAny<RuntimeException>(() => {
var method = block.CreateDelegate<Func<TestContextClass, BslValue>>();
});
Assert.Contains("Слишком много фактических параметров", runtimeException.Message);
}

[Fact]
public void Can_Call_Member_Procedures_On_Dynamics()
{
Expand Down
Loading