Skip to content

[WIP] Проброс bsl-процесса при native-компиляции.#1674

Open
dmpas wants to merge 3 commits intodevelopfrom
feature/issue-1673-native-compile
Open

[WIP] Проброс bsl-процесса при native-компиляции.#1674
dmpas wants to merge 3 commits intodevelopfrom
feature/issue-1673-native-compile

Conversation

@dmpas
Copy link
Copy Markdown
Collaborator

@dmpas dmpas commented May 6, 2026

Summary by CodeRabbit

  • Bug Fixes
    • Object methods that require an execution context parameter now receive it correctly during invocation, fixing incorrect call behavior for certain member procedures and functions.
  • Tests
    • Added tests to validate correct passing of the execution context parameter for member procedure and function calls.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 2026

📝 Walkthrough

Walkthrough

Introduces a private helper InjectedProcessNeeded(MethodInfo) in MethodCompiler to decide when an IBslProcess should be injected (either by ContextMethodInfo.InjectsProcess or when the method's first parameter is IBslProcess). The helper is used when preparing call arguments for object procedure/function and general method calls; tests added.

Changes

Process injection detection and call preparation

Layer / File(s) Summary
Detection helper
src/OneScript.Native/Compiler/MethodCompiler.cs
Add private static InjectedProcessNeeded(MethodInfo methodInfo) that returns true if methodInfo is ContextMethodInfo with InjectsProcess or its first parameter is IBslProcess.
Call sites — object procedure
src/OneScript.Native/Compiler/MethodCompiler.cs
VisitObjectProcedureCall computes injectProcess via InjectedProcessNeeded and passes it into PrepareCallArguments (replacing previous checks).
Call sites — object function
src/OneScript.Native/Compiler/MethodCompiler.cs
VisitObjectFunctionCall uses InjectedProcessNeeded(methodInfo) when preparing call arguments.
Call sites — general method calls
src/OneScript.Native/Compiler/MethodCompiler.cs
CreateMethodCall uses InjectedProcessNeeded(symbol.Method) for preparing call arguments.
Tests
src/Tests/OneScript.Core.Tests/NativeCompilerTest.cs
Add Can_Call_Member_ProceduresWithBslProcess and Can_Call_Member_FunctionsWithBslProcess to verify member procedures/functions receive an IBslProcess parameter when expected.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 I sniffed the method's first tiny clue,

If it's a process, I'll hop right through.
A helper decides, no fuss, no fight,
Injecting the process to make calls right. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is in Russian and refers to passing a BSL process during native compilation, which directly aligns with the main changes introducing InjectedProcessNeeded helper and updating process parameter injection logic.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/issue-1673-native-compile

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/OneScript.Native/Compiler/MethodCompiler.cs (1)

1163-1181: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

VisitObjectFunctionCall does not apply HasProcessParameter — argument misalignment at runtime

VisitObjectProcedureCall (lines 1112–1113) now injects the process argument whenever HasProcessParameter is true. However, VisitObjectFunctionCall (line 1180) still uses only InjectsProcess, so the same native method called in a function position (i.e., as an expression) will have injectsProcess = false, causing PrepareCallArguments to map the first script argument into the IBslProcess slot and shift all remaining arguments by one — a runtime type error or silent wrong-argument binding.

🐛 Proposed fix — mirror the procedure-call logic
-                var args = PrepareCallArguments(call.ArgumentList, methodInfo.GetParameters(), methodInfo is ContextMethodInfo { InjectsProcess: true });
+                var injectProcess = methodInfo is ContextMethodInfo { InjectsProcess: true } || HasProcessParameter(methodInfo);
+                var args = PrepareCallArguments(call.ArgumentList, methodInfo.GetParameters(), injectProcess);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/OneScript.Native/Compiler/MethodCompiler.cs` around lines 1163 - 1181,
VisitObjectFunctionCall fails to mirror VisitObjectProcedureCall's logic for
injecting the process parameter, causing argument misalignment; update
VisitObjectFunctionCall (around where methodInfo is obtained) to compute the
same injectsProcess flag used in PrepareCallArguments — i.e. treat a method as
injecting the process when methodInfo is a ContextMethodInfo with InjectsProcess
== true OR when methodInfo.HasProcessParameter() (or the equivalent
HasProcessParameter member) — then pass that injectsProcess into
PrepareCallArguments so function calls and procedure calls use the same argument
mapping.
🧹 Nitpick comments (1)
src/OneScript.Native/Compiler/MethodCompiler.cs (1)

1095-1100: 💤 Low value

Minor: method body can be reduced to a single expression

The if/return true/return false pattern is unnecessarily verbose.

♻️ Proposed simplification
 private static bool HasProcessParameter(MethodInfo mi)
 {
     var p = mi.GetParameters();
-    if (p.Length > 0 && p[0].ParameterType == typeof(IBslProcess)) return true;
-    return false;
+    return p.Length > 0 && p[0].ParameterType == typeof(IBslProcess);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/OneScript.Native/Compiler/MethodCompiler.cs` around lines 1095 - 1100,
The method HasProcessParameter currently uses an if/return true/return false
pattern; simplify it to a single expression by returning the boolean check
directly (inspect the first parameter of MethodInfo mi and compare its
ParameterType to typeof(IBslProcess)). Replace the block inside
HasProcessParameter with a single return expression (or make the method
expression-bodied) using mi.GetParameters() (or the local p variable) and the
check p.Length > 0 && p[0].ParameterType == typeof(IBslProcess).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/OneScript.Native/Compiler/MethodCompiler.cs`:
- Around line 1163-1181: VisitObjectFunctionCall fails to mirror
VisitObjectProcedureCall's logic for injecting the process parameter, causing
argument misalignment; update VisitObjectFunctionCall (around where methodInfo
is obtained) to compute the same injectsProcess flag used in
PrepareCallArguments — i.e. treat a method as injecting the process when
methodInfo is a ContextMethodInfo with InjectsProcess == true OR when
methodInfo.HasProcessParameter() (or the equivalent HasProcessParameter member)
— then pass that injectsProcess into PrepareCallArguments so function calls and
procedure calls use the same argument mapping.

---

Nitpick comments:
In `@src/OneScript.Native/Compiler/MethodCompiler.cs`:
- Around line 1095-1100: The method HasProcessParameter currently uses an
if/return true/return false pattern; simplify it to a single expression by
returning the boolean check directly (inspect the first parameter of MethodInfo
mi and compare its ParameterType to typeof(IBslProcess)). Replace the block
inside HasProcessParameter with a single return expression (or make the method
expression-bodied) using mi.GetParameters() (or the local p variable) and the
check p.Length > 0 && p[0].ParameterType == typeof(IBslProcess).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1ca6af39-d02f-449a-b33c-ce0d03beb3fd

📥 Commits

Reviewing files that changed from the base of the PR and between c455964 and 264d7d3.

📒 Files selected for processing (1)
  • src/OneScript.Native/Compiler/MethodCompiler.cs

@sonar-openbsl-ru-qa-bot
Copy link
Copy Markdown

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/Tests/OneScript.Core.Tests/NativeCompilerTest.cs (1)

871-906: ⚡ Quick win

Add observable assertions to these new process-injection tests.

Right now both tests only prove “does not throw”. In particular, Line 899 assigns the function result but never checks it, so the test would still pass if ВызватьМетод returned the wrong value. Please assert a real outcome here: e.g. seed Массив, verify the returned Количество, and make the procedure test sort a non-trivial ValueListImpl and check the order afterwards.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Tests/OneScript.Core.Tests/NativeCompilerTest.cs` around lines 871 - 906,
Update the two tests to include observable assertions: in
Can_Call_Member_FunctionsWithBslProcess seed the ArrayImpl with a known number
of elements, call the generated delegate (which executes block.CodeBlock calling
Рефлектор.ВызватьМетод) and Assert that the returned BslValue represents the
expected count; in Can_Call_Member_ProceduresWithBslProcess populate a
ValueListImpl with a non-trivial sequence, call the delegate (which runs
Список.СортироватьПоЗначению), then Assert the list is sorted as expected by
inspecting ValueListImpl contents. Use the existing method delegates,
ReflectorContext.CreateNew, ValueListImpl and ArrayImpl instances and convert
the returned BslValue to a concrete value for assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/OneScript.Native/Compiler/MethodCompiler.cs`:
- Around line 1095-1107: PrepareCallArguments currently miscomputes parameter
indexes for methods where InjectedProcessNeeded(MethodInfo) is true (explicit
IBslProcess first parameter), causing declaredParameters[decl] to be accessed
incorrectly; modify PrepareCallArguments to detect injected parameters via
InjectedProcessNeeded(methodInfo) and exclude that injected parameter from the
"remaining count" and any indexing math: treat the declared parameter list as
starting at index 1 when injected (or equivalently subtract 1 from declared
parameter count and shift declared index access by +1 when reading
declaredParameters[decl]) so arity checks and error messages count only
script-visible parameters and attempts to read declaredParameters use the
adjusted index (references: PrepareCallArguments, InjectedProcessNeeded,
declaredParameters, decl, IBslProcess).

---

Nitpick comments:
In `@src/Tests/OneScript.Core.Tests/NativeCompilerTest.cs`:
- Around line 871-906: Update the two tests to include observable assertions: in
Can_Call_Member_FunctionsWithBslProcess seed the ArrayImpl with a known number
of elements, call the generated delegate (which executes block.CodeBlock calling
Рефлектор.ВызватьМетод) and Assert that the returned BslValue represents the
expected count; in Can_Call_Member_ProceduresWithBslProcess populate a
ValueListImpl with a non-trivial sequence, call the delegate (which runs
Список.СортироватьПоЗначению), then Assert the list is sorted as expected by
inspecting ValueListImpl contents. Use the existing method delegates,
ReflectorContext.CreateNew, ValueListImpl and ArrayImpl instances and convert
the returned BslValue to a concrete value for assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c3e500f3-1fb7-4742-9d1e-979228b0de00

📥 Commits

Reviewing files that changed from the base of the PR and between 264d7d3 and f9975ad.

📒 Files selected for processing (2)
  • src/OneScript.Native/Compiler/MethodCompiler.cs
  • src/Tests/OneScript.Core.Tests/NativeCompilerTest.cs

Comment on lines +1095 to +1107
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;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Handle process-only methods in the arity logic.

Once this helper starts treating explicit IBslProcess-first methods as injected, calls to a method whose reflected signature is only (IBslProcess process) can hit declaredParameters[1] inside PrepareCallArguments when the script passes any extra argument. That turns a normal “too many actual parameters” error into an exception/generic compile failure.

Please update PrepareCallArguments so injected parameters are excluded from the remaining-count/indexing math before reading declaredParameters[decl]. A case like Список.СортироватьПоЗначению(1) should be reported as an arity error, not crash the compiler.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/OneScript.Native/Compiler/MethodCompiler.cs` around lines 1095 - 1107,
PrepareCallArguments currently miscomputes parameter indexes for methods where
InjectedProcessNeeded(MethodInfo) is true (explicit IBslProcess first
parameter), causing declaredParameters[decl] to be accessed incorrectly; modify
PrepareCallArguments to detect injected parameters via
InjectedProcessNeeded(methodInfo) and exclude that injected parameter from the
"remaining count" and any indexing math: treat the declared parameter list as
starting at index 1 when injected (or equivalently subtract 1 from declared
parameter count and shift declared index access by +1 when reading
declaredParameters[decl]) so arity checks and error messages count only
script-visible parameters and attempts to read declaredParameters use the
adjusted index (references: PrepareCallArguments, InjectedProcessNeeded,
declaredParameters, decl, IBslProcess).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant