Fix C++ POU local state variables - #934
Conversation
WalkthroughC++ POU processing and generation now preserve local variables, emit them as per-instance state, and exclude the runtime-only ChangesC++ POU state handling
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant preprocessPous
participant compilerModule
participant generateSTCode
participant generateCBlocksHeader
participant generateCBlocksCode
preprocessPous->>compilerModule: provide augmented POU variables
compilerModule->>generateSTCode: generate state pointer assignments
compilerModule->>generateCBlocksHeader: provide merged POU metadata
compilerModule->>generateCBlocksCode: provide merged POU metadata
generateCBlocksHeader->>generateCBlocksCode: generate per-instance state fields and mappings
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
e87be2b to
0553dc9
Compare
|
Updated in commit 0553dc9. The desktop compiler now keeps the generated ST bridge, c_blocks.h, and c_blocks_code.cpp aligned. This fixes the PREVSEQ/PREV_SEND missing-member errors during Arduino pre-compilation. |
0553dc9 to
f97cd28
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/backend/editor/compiler/compiler-module.ts (1)
2805-2806: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winAdapt
PLCProjectDatabefore callingfromSchemaShape.
PLCProjectDatadefinesconfigurations, butfromSchemaShapereadsdata.configuration?.resource. The cast suppresses the mismatch, causing debug-generated ST to omit tasks, instances, and global variables.🤖 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/backend/editor/compiler/compiler-module.ts` around lines 2805 - 2806, Update the compiler flow around fromSchemaShape and runJsonTranspiler to adapt PLCProjectData’s configurations field into the configuration shape expected by fromSchemaShape, rather than suppressing the mismatch with a cast. Ensure the adapted data preserves configuration resources so generated ST includes tasks, instances, and global variables.
🤖 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/backend/editor/compiler/compiler-module.ts`:
- Around line 89-94: Update the processed POU lookup in the compiler module to
match `projectData.pous` entries by their top-level `name` field instead of
`pou.data.name`, and read variables from `interface.variables` rather than
`data.variables`. Preserve the fallback to `cppPou.variables` when no matching
variables are available.
---
Outside diff comments:
In `@src/backend/editor/compiler/compiler-module.ts`:
- Around line 2805-2806: Update the compiler flow around fromSchemaShape and
runJsonTranspiler to adapt PLCProjectData’s configurations field into the
configuration shape expected by fromSchemaShape, rather than suppressing the
mismatch with a cast. Ensure the adapted data preserves configuration resources
so generated ST includes tasks, instances, and global variables.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 1902709b-3b82-49c5-9857-ae6e3d52f15b
📒 Files selected for processing (10)
src/backend/editor/compiler/compiler-module.tssrc/backend/shared/utils/PLC/__tests__/preprocess-pous.test.tssrc/backend/shared/utils/PLC/preprocess-pous.tssrc/backend/shared/utils/cpp/__tests__/generateCBlocksCode.test.tssrc/backend/shared/utils/cpp/__tests__/generateCBlocksHeader.test.tssrc/backend/shared/utils/cpp/generateCBlocksCode.tssrc/backend/shared/utils/cpp/generateCBlocksHeader.tssrc/frontend/utils/cpp/__tests__/generateSTCode.test.tssrc/frontend/utils/cpp/cppPouVariables.tssrc/frontend/utils/cpp/generateSTCode.ts
🚧 Files skipped from review as they are similar to previous changes (8)
- src/backend/shared/utils/cpp/tests/generateCBlocksHeader.test.ts
- src/backend/shared/utils/cpp/generateCBlocksHeader.ts
- src/frontend/utils/cpp/generateSTCode.ts
- src/frontend/utils/cpp/cppPouVariables.ts
- src/backend/shared/utils/PLC/preprocess-pous.ts
- src/frontend/utils/cpp/tests/generateSTCode.test.ts
- src/backend/shared/utils/cpp/generateCBlocksCode.ts
- src/backend/shared/utils/cpp/tests/generateCBlocksCode.test.ts
|
Follow-up on the outside-diff CodeRabbit finding about |
dc11b2c to
d233b6c
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/backend/editor/compiler/compiler-module.ts`:
- Around line 82-98: Update getCppPousForGeneration to use the inferred type
from projectData.pous.find directly, removing the unchecked cast around
processedPou. Delete the now-unused PLCVariable import while preserving the
existing variables fallback behavior.
- Around line 82-98: Replace the type assertion in getCppPousForGeneration with
an explicit type guard that validates the matched POU has a data object before
accessing data.variables. Preserve the existing fallback to cppPou.variables
when no valid processed POU or variables are available.
🪄 Autofix
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: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 595e073a-ac65-4cba-8b6d-195e94471c85
📒 Files selected for processing (10)
src/backend/editor/compiler/compiler-module.tssrc/backend/shared/utils/PLC/__tests__/preprocess-pous.test.tssrc/backend/shared/utils/PLC/preprocess-pous.tssrc/backend/shared/utils/cpp/__tests__/generateCBlocksCode.test.tssrc/backend/shared/utils/cpp/__tests__/generateCBlocksHeader.test.tssrc/backend/shared/utils/cpp/generateCBlocksCode.tssrc/backend/shared/utils/cpp/generateCBlocksHeader.tssrc/frontend/utils/cpp/__tests__/generateSTCode.test.tssrc/frontend/utils/cpp/cppPouVariables.tssrc/frontend/utils/cpp/generateSTCode.ts
🚧 Files skipped from review as they are similar to previous changes (9)
- src/frontend/utils/cpp/generateSTCode.ts
- src/backend/shared/utils/cpp/tests/generateCBlocksHeader.test.ts
- src/backend/shared/utils/PLC/preprocess-pous.ts
- src/backend/shared/utils/cpp/generateCBlocksHeader.ts
- src/frontend/utils/cpp/tests/generateSTCode.test.ts
- src/backend/shared/utils/cpp/generateCBlocksCode.ts
- src/backend/shared/utils/PLC/tests/preprocess-pous.test.ts
- src/backend/shared/utils/cpp/tests/generateCBlocksCode.test.ts
- src/frontend/utils/cpp/cppPouVariables.ts
| /** | ||
| * Keep generated C++ metadata aligned with the POU interfaces used to build | ||
| * the ST bridge. The sidecar carries the original C++ source, while the | ||
| * preprocessed POU is the authoritative source for its current variables. | ||
| */ | ||
| const getCppPousForGeneration = (projectData: ProjectDataWithCppPous): CppPouDataCode[] => { | ||
| return (projectData.originalCppPous ?? []).map((cppPou) => { | ||
| const processedPou = projectData.pous.find((pou) => pou.data.name === cppPou.name) as | ||
| | { data?: { variables?: PLCVariable[] } } | ||
| | undefined | ||
| return { | ||
| ...cppPou, | ||
| variables: processedPou?.data?.variables ?? cppPou.variables, | ||
| } | ||
| }) | ||
| } | ||
|
|
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 5 'PLCProjectData|originalCppPous|toIpcProjectData|pou\.data\.variables' srcRepository: Autonomy-Logic/openplc-editor
Length of output: 50386
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- compiler module ---'
sed -n '1,120p' src/backend/editor/compiler/compiler-module.ts
printf '%s\n' '--- shared type declarations ---'
rg -n -C 6 'export (type|interface) (PLCProjectData|PLCPou|PLCVariable)|type (PLCProjectData|PLCPou|PLCVariable)' \
src/backend/shared/types/PLC src/middleware/shared/ports/types.ts
printf '%s\n' '--- preprocess and metadata flow ---'
rg -n -C 8 'function preprocessPous|const preprocessPous|preprocessPous\(|originalCppPous|getCppPousForGeneration|generateCBlocks(Header|Code)' \
src/backend src/middleware src/mainRepository: Autonomy-Logic/openplc-editor
Length of output: 50386
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- imports and exact helper context ---'
sed -n '116,145p' src/backend/editor/compiler/compiler-module.ts
sed -n '82,100p' src/backend/editor/compiler/compiler-module.ts
printf '%s\n' '--- POU schema definitions ---'
sed -n '80,175p' src/backend/shared/types/PLC/open-plc.ts
sed -n '210,275p' src/backend/shared/types/PLC/open-plc.ts
sed -n '820,865p' src/backend/shared/types/PLC/open-plc.ts
printf '%s\n' '--- C++ sidecar types and generator contracts ---'
sed -n '1,180p' src/backend/shared/utils/cpp/generateCBlocksCode.ts
sed -n '1,140p' src/backend/shared/utils/cpp/generateCBlocksHeader.ts
printf '%s\n' '--- helper call sites ---'
rg -n -C 4 'getCppPousForGeneration' src/backend/editor/compiler/compiler-module.tsRepository: Autonomy-Logic/openplc-editor
Length of output: 18915
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
import re
compiler = Path("src/backend/editor/compiler/compiler-module.ts").read_text()
schema = Path("src/backend/shared/types/PLC/open-plc.ts").read_text()
assert "projectData.pous.find((pou) => pou.data.name === cppPou.name) as" in compiler
assert re.search(
r"import type \{ PlatformOption, PLCVariable \} from .*ports/types",
compiler,
)
assert len(re.findall(r"\bPLCVariable\b", compiler)) == 1, "PLCVariable has other uses"
pou_schema = schema[schema.index("const PLCPouSchema"):schema.index("type PLCPou =")]
variants = re.findall(
r"z\.object\(\{\s*type: z\.literal\('[^']+'\),\s*data: (PLC\w+Schema)",
pou_schema,
)
assert variants == ["PLCProgramSchema", "PLCFunctionSchema", "PLCFunctionBlockSchema"]
for name in variants:
match = re.search(
rf"const {name} = z\.object\(\{{(.*?)\n\}}\)",
schema,
re.S,
)
assert match and re.search(r"\bvariables:\s*z\.array\(PLCVariableSchema\)", match.group(1)), name
print("The assertion is present.")
print("PLCVariable is imported only for the assertion.")
print("Every PLCPou variant exposes data.variables as PLCVariable[].")
print("The inferred backend POU type is sufficient for the proposed assertion removal.")
PYRepository: Autonomy-Logic/openplc-editor
Length of output: 284
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n '\bPLCVariable\b' src/backend/editor/compiler/compiler-module.tsRepository: Autonomy-Logic/openplc-editor
Length of output: 313
Remove the unchecked POU type assertion.
PLCProjectData already exposes pou.data.variables as PLCVariable[] for every POU variant. Remove the assertion and the unused PLCVariable import.
Proposed fix
-import type { PlatformOption, PLCVariable } from '../../../middleware/shared/ports/types'
+import type { PlatformOption } from '../../../middleware/shared/ports/types'
- const processedPou = projectData.pous.find((pou) => pou.data.name === cppPou.name) as
- | { data?: { variables?: PLCVariable[] } }
- | undefined
+ const processedPou = projectData.pous.find((pou) => pou.data.name === cppPou.name)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /** | |
| * Keep generated C++ metadata aligned with the POU interfaces used to build | |
| * the ST bridge. The sidecar carries the original C++ source, while the | |
| * preprocessed POU is the authoritative source for its current variables. | |
| */ | |
| const getCppPousForGeneration = (projectData: ProjectDataWithCppPous): CppPouDataCode[] => { | |
| return (projectData.originalCppPous ?? []).map((cppPou) => { | |
| const processedPou = projectData.pous.find((pou) => pou.data.name === cppPou.name) as | |
| | { data?: { variables?: PLCVariable[] } } | |
| | undefined | |
| return { | |
| ...cppPou, | |
| variables: processedPou?.data?.variables ?? cppPou.variables, | |
| } | |
| }) | |
| } | |
| /** | |
| * Keep generated C++ metadata aligned with the POU interfaces used to build | |
| * the ST bridge. The sidecar carries the original C++ source, while the | |
| * preprocessed POU is the authoritative source for its current variables. | |
| */ | |
| const getCppPousForGeneration = (projectData: ProjectDataWithCppPous): CppPouDataCode[] => { | |
| return (projectData.originalCppPous ?? []).map((cppPou) => { | |
| const processedPou = projectData.pous.find((pou) => pou.data.name === cppPou.name) | |
| return { | |
| ...cppPou, | |
| variables: processedPou?.data?.variables ?? cppPou.variables, | |
| } | |
| }) | |
| } |
🧰 Tools
🪛 ast-grep (0.45.1)
[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { spawn } from 'node:child_process'
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(detect-child-process-typescript)
🤖 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/backend/editor/compiler/compiler-module.ts` around lines 82 - 98, Update
getCppPousForGeneration to use the inferred type from projectData.pous.find
directly, removing the unchecked cast around processedPou. Delete the now-unused
PLCVariable import while preserving the existing variables fallback behavior.
Source: Coding guidelines
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 8 'originalCppPous|preprocessPous|getCppPousForGeneration|handleGenerateCBlocks(Header|Code)|compileForDebugger|toIpcProjectData' srcRepository: Autonomy-Logic/openplc-editor
Length of output: 50386
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- compiler-module symbols ---'
rg -n -C 10 'getCppPousForGeneration|compileProgram|compileForDebugger|handleGenerateCBlocksHeader|handleGenerateCBlocksCode|originalCppPous|projectData\.pous' src/backend/editor/compiler/compiler-module.ts
printf '%s\n' '--- preprocessing and conversion ---'
sed -n '1,210p' src/backend/shared/utils/PLC/preprocess-pous.ts
sed -n '1,90p' src/middleware/adapters/editor/compiler-adapter.ts
sed -n '160,325p' src/middleware/adapters/editor/compiler-adapter.ts
printf '%s\n' '--- compiler module entry-point declarations and call sites ---'
rg -n -C 12 'compileProgram|compileForDebugger|handleGenerateCBlocks(Header|Code)' src/backend/editor/compiler/compiler-module.ts src/main/modules/ipc/main.tsRepository: Autonomy-Logic/openplc-editor
Length of output: 50385
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- compileProgram data flow ---'
sed -n '2408,2575p' src/backend/editor/compiler/compiler-module.ts
sed -n '2575,2924p' src/backend/editor/compiler/compiler-module.ts
printf '%s\n' '--- compileForDebugger data flow ---'
sed -n '2924,3122p' src/backend/editor/compiler/compiler-module.ts
printf '%s\n' '--- exact adapter conversion and preprocess call sites ---'
sed -n '176,215p' src/middleware/adapters/editor/compiler-adapter.ts
sed -n '286,320p' src/middleware/adapters/editor/compiler-adapter.ts
printf '%s\n' '--- pipeline C++ consumers ---'
rg -n -C 6 'buildCBlocksFromPous|handleGenerateCBlocks(Header|Code)|originalCppPous|runCompilePipeline' src/backend/shared/compile src/backend/editor/compiler/compiler-module.ts
printf '%s\n' '--- type and shape declarations ---'
rg -n -C 5 'interface .*Pou|type .*Pou|PLCProjectData|IpcProjectData|CppPouDataCode|PLCVariable' src/middleware/shared/ports/types.ts src/backend/editor/compiler/compiler-module.tsRepository: Autonomy-Logic/openplc-editor
Length of output: 50386
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
adapter = Path("src/middleware/adapters/editor/compiler-adapter.ts").read_text()
preprocess = Path("src/backend/shared/utils/PLC/preprocess-pous.ts").read_text()
compiler = Path("src/backend/editor/compiler/compiler-module.ts").read_text()
pipeline = Path("src/backend/shared/compile/pipeline.ts").read_text()
def require(text, needle, label):
if needle not in text:
raise AssertionError(f"missing {label}: {needle}")
def ordered(text, needles, label):
positions = [text.index(needle) for needle in needles]
if positions != sorted(positions):
raise AssertionError(f"wrong order in {label}: {positions}")
# Build and debugger both preprocess, then convert the processed result.
require(adapter, "const { projectData: processedData, validationFailed } = preprocessPous(", "build preprocessing")
require(adapter, "const ipcData = toIpcProjectData(processedData)", "build IPC conversion")
require(adapter, "async compileForDebug(", "debug entry point")
debug = adapter[adapter.index("async compileForDebug("):]
require(debug, "const { projectData: processedData, validationFailed } = preprocessPous(", "debug preprocessing")
require(debug, "const ipcData = toIpcProjectData(processedData)", "debug IPC conversion")
# The converter forwards the sidecar when it exists.
require(adapter, "...(data.originalCppPous ? { originalCppPous:", "sidecar forwarding")
# C++ preprocessing records variables after local-variable augmentation and
# replaces the C++ POU body only after the sidecar is assembled.
ordered(
preprocess,
[
"processedProjectData = addCppLocalVariables(processedProjectData)",
"const originalCppPousData = processedProjectData.pous",
"processedProjectData.pous = processedProjectData.pous.map",
"projectDataWithCpp.originalCppPous = originalCppPousData",
],
"C++ preprocessing",
)
# compileProgram passes the received projectData to the shared pipeline.
require(compiler, "const result = await runCompilePipeline(", "compileProgram pipeline call")
compile_call = compiler[compiler.index("const result = await runCompilePipeline("):]
require(compile_call, "projectData,", "compileProgram projectData handoff")
# The debugger uses the sidecar and generated header/code helpers.
debug_backend = compiler[compiler.index("async compileForDebugger("):]
for needle in (
"originalCppPous?.length",
"await this.handleGenerateCBlocksHeader(projectData",
"await this.handleGenerateCBlocksCode(projectData",
):
require(debug_backend, needle, f"debug backend consumer {needle}")
# The shared pipeline consumes the sidecar for C-block generation.
require(pipeline, "const originalCppPous = processedData.originalCppPous ?? []", "pipeline sidecar read")
require(pipeline, "buildCBlocksFromPous(originalCppPous as never)", "pipeline C-block generation")
print("metadata flow checks passed")
PYRepository: Autonomy-Logic/openplc-editor
Length of output: 354
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
adapter = Path("src/middleware/adapters/editor/compiler-adapter.ts").read_text()
preprocess = Path("src/backend/shared/utils/PLC/preprocess-pous.ts").read_text()
compiler = Path("src/backend/editor/compiler/compiler-module.ts").read_text()
pipeline = Path("src/backend/shared/compile/pipeline.ts").read_text()
def require(text, needle, label):
if needle not in text:
raise AssertionError(f"missing {label}: {needle}")
def ordered(text, needles, label):
positions = [text.index(needle) for needle in needles]
if positions != sorted(positions):
raise AssertionError(f"wrong order in {label}: {positions}")
build = adapter[:adapter.index("async compileForDebug(")]
debug = adapter[adapter.index("async compileForDebug("):]
require(build, "const { projectData: processedData, validationFailed } = preprocessPous(", "build preprocessing")
require(build, "const ipcData = toIpcProjectData(processedData)", "build IPC conversion")
require(debug, "const { projectData: processedData, validationFailed } = preprocessPous(", "debug preprocessing")
require(debug, "const ipcData = toIpcProjectData(processedData)", "debug IPC conversion")
require(adapter, "...(data.originalCppPous ? { originalCppPous:", "sidecar forwarding")
cpp_start = preprocess.index("// --- C++ processing ---")
cpp_end = preprocess.index("// --- SoftMotion:", cpp_start)
cpp = preprocess[cpp_start:cpp_end]
ordered(
cpp,
[
"processedProjectData = addCppLocalVariables(processedProjectData)",
"const originalCppPousData = processedProjectData.pous",
"processedProjectData.pous = processedProjectData.pous.map",
"projectDataWithCpp.originalCppPous = originalCppPousData",
],
"C++ preprocessing",
)
compile_start = compiler.index("const result = await runCompilePipeline(")
compile_call = compiler[compile_start:]
require(compile_call, "projectData,", "compileProgram projectData handoff")
debug_backend = compiler[compiler.index("async compileForDebugger("):]
for needle in (
"originalCppPous?.length",
"await this.handleGenerateCBlocksHeader(projectData",
"await this.handleGenerateCBlocksCode(projectData",
):
require(debug_backend, needle, f"debug backend consumer {needle}")
require(pipeline, "const originalCppPous = processedData.originalCppPous ?? []", "pipeline sidecar read")
require(pipeline, "buildCBlocksFromPous(originalCppPous as never)", "pipeline C-block generation")
print("metadata flow checks passed")
PYRepository: Autonomy-Logic/openplc-editor
Length of output: 195
Replace the type assertion with explicit narrowing. The assertion violates the TypeScript guidelines and bypasses validation of the IPC POU shape. Use a type guard before reading data.variables.
🧰 Tools
🪛 ast-grep (0.45.1)
[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { spawn } from 'node:child_process'
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(detect-child-process-typescript)
🤖 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/backend/editor/compiler/compiler-module.ts` around lines 82 - 98, Replace
the type assertion in getCppPousForGeneration with an explicit type guard that
validates the matched POU has a data object before accessing data.variables.
Preserve the existing fallback to cppPou.variables when no valid processed POU
or variables are available.
Summary
Fix C/C++ POU local variables so they are generated as per-instance state instead of being omitted from the generated C++ bridge.
Previously, only input and output variables were included in the generated
*_VARSstructs, ST pointer assignments, and C++ macros. Local variables declared on a C/C++ Function Block POU, such asPrevSeq, were referenced by user code but never declared in the generated C++ scope.Changes
localvariables, along withinput,output, andinOut, in generated C++ POU structs and macros.hasBeenInitializedsetup guard internal to the ST stub so it is not exposed as a user C++ macro or struct field.PrevSeq.Closes #933
Validation
npx jest src/frontend/utils/cpp/__tests__/generateSTCode.test.ts src/backend/shared/utils/cpp/__tests__/generateCBlocksCode.test.ts src/backend/shared/utils/cpp/__tests__/generateCBlocksHeader.test.ts src/backend/shared/utils/PLC/__tests__/preprocess-pous.test.ts --runInBandnpx eslint src/frontend/utils/cpp/cppPouVariables.ts src/frontend/utils/cpp/generateSTCode.ts src/backend/shared/utils/cpp/generateCBlocksCode.ts src/backend/shared/utils/cpp/generateCBlocksHeader.tsSummary by CodeRabbit
hasBeenInitialized, are no longer emitted as struct fields or user-visible macro tokens.