diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index eb3559a83..987214821 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -39,12 +39,6 @@ else echo " WARNING: matiec binary not found at $BIN_DIR/iec2c" fi -if [ -f "$BIN_DIR/xml2st" ]; then - echo " xml2st binary ($NODE_ARCH): OK" -else - echo " WARNING: xml2st binary not found at $BIN_DIR/xml2st" -fi - # Fix Electron sandbox for container (chrome-sandbox needs SUID root + mode 4755) CHROME_SANDBOX="node_modules/electron/dist/chrome-sandbox" if [ -f "$CHROME_SANDBOX" ]; then diff --git a/.gitattributes b/.gitattributes index a9cb934ad..1aa57117b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -15,5 +15,4 @@ # Identification for binary files used as compilers/transpilers ########################## iec2c binary -xml2st binary resources/bin/**/* binary \ No newline at end of file diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 63f9ce50b..4a8f9734d 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -20,7 +20,7 @@ jobs: - name: Install dependencies run: npm ci --ignore-scripts - - name: Download strucpp + xml2st binaries + - name: Download strucpp binaries # tsc needs the strucpp package to resolve the types imported # from `backend/shared/library/strucpp-runtime.ts` and friends. # Run the binary downloader directly (skipping the rest of diff --git a/.github/workflows/ci-unit-tests.yml b/.github/workflows/ci-unit-tests.yml index c19cebca2..ef15d6f76 100644 --- a/.github/workflows/ci-unit-tests.yml +++ b/.github/workflows/ci-unit-tests.yml @@ -23,7 +23,7 @@ jobs: # --ignore-scripts skips the postinstall, so strucpp (a GitHub-release # package, not an npm dep) is never fetched — yet the TS sources import # `strucpp/libs/iec-types.json` and its runtime headers. Install just - # strucpp (no xml2st platform binary, no native rebuild) so the suites + # strucpp (no native rebuild) so the suites # can load and the coverage gate actually runs. - name: Install strucpp run: npm run setup:strucpp diff --git a/src/backend/editor/compiler/compiler-module.ts b/src/backend/editor/compiler/compiler-module.ts index f2ee0bbc2..6a3ae3cdb 100644 --- a/src/backend/editor/compiler/compiler-module.ts +++ b/src/backend/editor/compiler/compiler-module.ts @@ -2316,7 +2316,7 @@ class CompilerModule { * Main compile entry point. Drives the full Step 0-13 flow * through the shared `runCompilePipeline` orchestrator * (`backend/shared/compile/pipeline.ts`); platform-specific bits - * (xml2st spawn, arduino-cli spawn, runtime upload) are abstracted + * (arduino-cli spawn, runtime upload) are abstracted * behind `EditorCompilerPlatformPort`. Single source of truth * for compile behaviour shared with openplc-web. */ diff --git a/src/backend/editor/utils/xml-manager.ts b/src/backend/editor/utils/xml-manager.ts index fa2facb6b..1b81ac30a 100644 --- a/src/backend/editor/utils/xml-manager.ts +++ b/src/backend/editor/utils/xml-manager.ts @@ -4,11 +4,11 @@ import { join } from 'path' /** * Create an xml file with the given params. Synchronous on * purpose, same reason `CreateJSONFile` is: every caller chains - * the next step (running xml2st on the file) immediately after, + * the next step (reading the file) immediately after, * and the previous async-fire-and-forget form returned success * before libuv had actually flushed the bytes — a fast subsequent * spawn could read 0 bytes. The compile pipeline never observed - * this in practice because xml2st spawns slowly enough that the + * this in practice because the read happened slowly enough that the * write usually won the race, but the API contract has always * been wrong. * diff --git a/src/backend/shared/compile/__tests__/pipeline-runtime-v3.test.ts b/src/backend/shared/compile/__tests__/pipeline-runtime-v3.test.ts index e06bb12a8..2d6308f7c 100644 --- a/src/backend/shared/compile/__tests__/pipeline-runtime-v3.test.ts +++ b/src/backend/shared/compile/__tests__/pipeline-runtime-v3.test.ts @@ -10,7 +10,7 @@ * core). These tests lock that ordering in. * * Kept in a separate file from `pipeline.test.ts` (which is stale from - * the xml2st→JSON-transpiler migration and references the removed + * the XML→JSON-transpiler migration and references the removed * `transpileXmlToSt` port method) so the v3 coverage compiles + runs * against the current `transpileToSt` contract. */ diff --git a/src/backend/shared/compile/__tests__/pipeline.test.ts b/src/backend/shared/compile/__tests__/pipeline.test.ts index afb213764..06f2f3353 100644 --- a/src/backend/shared/compile/__tests__/pipeline.test.ts +++ b/src/backend/shared/compile/__tests__/pipeline.test.ts @@ -161,7 +161,7 @@ describe('runCompilePipeline — simulator path', () => { expect(result.uploaded).toBe(false) expect(port.transpileToSt).toHaveBeenCalledTimes(1) // The pipeline hands the in-process transpiler the project IR plus - // a log callback — no XML / xml2st flags flow through anymore. + // a log callback — no XML / transpiler flags flow through anymore. expect(port.transpileToSt).toHaveBeenCalledWith( expect.objectContaining({ projectData: expect.anything() }), expect.any(Function), diff --git a/src/backend/shared/compile/__tests__/validate-empty-variables.test.ts b/src/backend/shared/compile/__tests__/validate-empty-variables.test.ts index 79be89510..b58d4b644 100644 --- a/src/backend/shared/compile/__tests__/validate-empty-variables.test.ts +++ b/src/backend/shared/compile/__tests__/validate-empty-variables.test.ts @@ -2,7 +2,7 @@ * Tests for the pre-compile blank-FBD-variable guard. * * An unnamed FBD input/output variable block becomes an empty - * `` in the PLCopen XML, which crashes xml2st with + * `` in the PLCopen XML, which the compiler rejects with * `'NoneType' object has no attribute 'split'`. These tests pin the * detector that lets the pipeline bail with a clear message — naming * what the block is wired to, or its position when it is wired to diff --git a/src/backend/shared/compile/pipeline.ts b/src/backend/shared/compile/pipeline.ts index 4e5d3fbec..c3922edf1 100644 --- a/src/backend/shared/compile/pipeline.ts +++ b/src/backend/shared/compile/pipeline.ts @@ -4,7 +4,7 @@ * Single source of truth for the full compile flow (Steps 0–13 in * the editor's canonical pipeline). Editor and web both drive this * function through a `CompilerPlatformPort`; the platform port - * abstracts the three places where platform truly differs (xml2st + * abstracts the three places where platform truly differs (ST transpiler * transport, arduino-cli transport, runtime upload transport). * Everything else — preprocessing, XML generation, strucpp compile, * conf authoring, defines authoring, bundle composition, ordering, @@ -238,7 +238,7 @@ export interface RunCompilePipelineArgs { export interface RunCompilePipelineResult { success: boolean - /** Structured strucpp + xml2st diagnostics from this run. Carries + /** Structured strucpp diagnostics from this run. Carries * the per-error events the renderer's navigation keys off. */ errors?: StructuredCompileError[] /** Compiled firmware bytes when the pipeline reached the @@ -385,10 +385,9 @@ async function runCompilePipelineInner( // --------------------------------------------------------------------- // Step 0b: Reject blank FBD variable blocks before XML generation. // - // An unnamed FBD in/out variable serialises to an empty - // ``, which makes xml2st crash with the opaque - // `'NoneType' object has no attribute 'split'`. Catch it here and - // tell the user exactly which POU to fix. + // An unnamed FBD in/out variable has no expression for the ST + // transpiler to emit, producing invalid code downstream. Catch it + // here and tell the user exactly which POU to fix. // --------------------------------------------------------------------- const emptyVariables = findEmptyFbdVariables(processedData) if (emptyVariables.length > 0) { @@ -411,7 +410,7 @@ async function runCompilePipelineInner( // so this hop never builds PLCOpen XML. Native STRUCT declarations // are the only emission mode the transpiler supports — the legacy // matiec struct→FB rewrite isn't ported, so there are no - // equivalents of the old `xml2stArgs` flags. + // equivalents of the old struct-rewrite flags. // --------------------------------------------------------------------- emit({ stage: 'st', message: 'Generating Structured Text...', level: 'info' }) // The pipeline carries the editor's schema-shape `PLCProjectData`, diff --git a/src/backend/shared/compile/steps/generate-defines.ts b/src/backend/shared/compile/steps/generate-defines.ts index 5820ac593..ecddca33e 100644 --- a/src/backend/shared/compile/steps/generate-defines.ts +++ b/src/backend/shared/compile/steps/generate-defines.ts @@ -48,7 +48,7 @@ export interface GenerateDefinesInput { * category (`DIN` / `AIN` / `DOUT` / `AOUT`) plus matching * count defines (`NUM_DISCRETE_INPUT` etc.). */ devicePinMapping: DevicePin[] - /** Concatenated ST program content (the output of xml2st). + /** Concatenated ST program content (the output of the ST transpiler). * Scanned with `String.prototype.includes` for the marker * function-block names that toggle the Arduino-library * `USE_*_BLOCK` defines. The set of marker strings here is diff --git a/src/backend/shared/compile/steps/validate-empty-variables.ts b/src/backend/shared/compile/steps/validate-empty-variables.ts index 97b6876e0..0d6f7f95a 100644 --- a/src/backend/shared/compile/steps/validate-empty-variables.ts +++ b/src/backend/shared/compile/steps/validate-empty-variables.ts @@ -4,7 +4,7 @@ import { PLCProjectData } from '../../types/PLC/open-plc' * An FBD variable block (input or output) whose name is blank. * * Such a block serialises to an empty `` in the PLCopen - * XML, which makes xml2st abort the whole compile with the opaque + * XML, which would make the compiler abort the whole compile with the opaque * `'NoneType' object has no attribute 'split'` error. We catch it * before XML generation and report it in terms the user can act on: * what the block is wired to, falling back to its canvas position when diff --git a/src/backend/shared/library/__tests__/build-pipeline.test.ts b/src/backend/shared/library/__tests__/build-pipeline.test.ts index fa0f37d12..178c37655 100644 --- a/src/backend/shared/library/__tests__/build-pipeline.test.ts +++ b/src/backend/shared/library/__tests__/build-pipeline.test.ts @@ -2,7 +2,7 @@ * Tests for the library build pipeline. * * `prepareXmlForLibraryBuild` no longer generates PLCopen XML — the - * old xml2st flow was replaced by an in-process JSON → ST transpiler. + * the legacy XML→ST flow was replaced by an in-process JSON → ST transpiler. * The function now only validates the manifest and returns the stubbed * project data (plus the POU inventory the splitter needs); the actual * transpile happens later via `LibraryBuildPort.transpileToSt`. @@ -422,7 +422,7 @@ describe('libraryBuildFromTranspiledSt', () => { it('drops `_config.st` so strucpp does not error on the stub configuration', () => { // The stub program (which the splitter recognises and the - // pipeline drops) is referenced by xml2st's emitted + // pipeline drops) is referenced by the transpiler's emitted // CONFIGURATION block. Leaving `_config.st` in the strucpp // inputs makes strucpp emit "Unknown program type 'MAIN'" // diagnostics because the stub source isn't there anymore. @@ -637,7 +637,7 @@ describe('libraryBuildFromTranspiledSt', () => { expect(res.success).toBe(true) }) - it('matches POU docs case-insensitively (xml2st upper-cases identifiers)', () => { + it('matches POU docs case-insensitively (the transpiler upper-cases identifiers)', () => { const archive = { manifest: { name: 'demo_lib', diff --git a/src/backend/shared/library/__tests__/program-build-helpers.test.ts b/src/backend/shared/library/__tests__/program-build-helpers.test.ts index 44bdf3684..4341fc156 100644 --- a/src/backend/shared/library/__tests__/program-build-helpers.test.ts +++ b/src/backend/shared/library/__tests__/program-build-helpers.test.ts @@ -235,7 +235,7 @@ describe('enrichErrorWithPouContext', () => { }) it('skips blank separator lines between END_VAR and the body', () => { - // The ST generators (`pou-text-serializer.ts` and xml2st on the + // The ST generators (`pou-text-serializer.ts` and the ST transpiler on the // compile path) insert blank lines after END_VAR for readability. // Those blanks live in the per-POU file the splitter feeds // strucpp but NOT in `pou.body.value`, which is what the body diff --git a/src/backend/shared/library/build-pipeline.ts b/src/backend/shared/library/build-pipeline.ts index 622eff878..8d026e6f0 100644 --- a/src/backend/shared/library/build-pipeline.ts +++ b/src/backend/shared/library/build-pipeline.ts @@ -7,15 +7,14 @@ * 1. `prepareXmlForLibraryBuild(project, manifest)` — synthesizes * a stub main program / task / instance into a transient * PLCProject (the on-disk project remains untouched) and runs - * the canonical XmlGenerator on it. xml2st rejects programless + * the canonical XmlGenerator on it. the ST transpiler rejects programless * projects, so the stub is mandatory; the stub's POU body is * intentionally non-empty (`LocalVar := 3;` against a single - * INT local) because some xml2st codepaths also reject empty + * INT local) because some ST-transpiler codepaths also reject empty * program bodies. * - * 2. *(caller runs xml2st on the resulting plc.xml — Electron - * spawns a local binary, web backend posts to its xml2st - * service — produces `program.st`.)* + * 2. *(the in-process ST transpiler runs on the project and + * produces `program.st`.)* * * 3. `libraryBuildFromTranspiledSt(programSt, knownPous, manifest)` * — splits `program.st` per-POU via the shared splitter, drops @@ -74,8 +73,8 @@ export interface LibraryBuildManifest { * console can render through the existing diagnostic pipeline. * * Strucpp itself validates manifests during compile, but doing it - * here lets the build fail BEFORE running xml2st when the manifest - * is obviously broken — saves a slow xml2st spawn on every + * here lets the build fail early when the manifest + * is obviously broken — saves wasted transpile work on every * mis-edited save. */ function parseLibraryManifest(json: string): ManifestParseResult { @@ -128,7 +127,7 @@ function parseLibraryManifest(json: string): ManifestParseResult { } // --------------------------------------------------------------------------- -// Stub program — makes xml2st accept a programless library project +// Stub program — makes the ST transpiler accept a programless library project // --------------------------------------------------------------------------- /** @@ -147,14 +146,14 @@ const STUB_INSTANCE_NAME = '__openplc_library_stub_instance__' /** * Build a transient PLCProject with a stub main program added on * top of the library's POUs / data types. The stub is what - * satisfies xml2st (and strucpp's main-program assumption later in + * satisfies the ST transpiler (and strucpp's main-program assumption later in * the verification path). Caller drops the stub's per-POU output * before handing the remaining sources to compileStlib. * - * The stub's body is non-empty (`LocalVar := 3;`) because xml2st + * The stub's body is non-empty (`LocalVar := 3;`) because the ST transpiler * has been observed to reject programs with completely empty bodies * — a single trivial assignment + a single INT local is the smallest - * shape that gets accepted across every xml2st version. + * shape that gets accepted across transpiler versions. */ function stubProgramFor(project: PLCProject): PLCProject { return { @@ -204,14 +203,14 @@ function stubProgramFor(project: PLCProject): PLCProject { * Synthetic filename the splitter emits for the stub program. The * splitter writes its file keys using the caller-side POU name * verbatim (case preserved), so this matches what `splitProgramSt` - * returns regardless of how xml2st upper-cases identifiers in the + * returns regardless of how the transpiler upper-cases identifiers in the * monolithic ST output. Caller drops this entry before feeding the * rest to compileStlib. */ const STUB_SPLIT_FILENAME = `${STUB_PROGRAM_NAME}.st` // --------------------------------------------------------------------------- -// Stage 1: pre-xml2st (pure) +// Stage 1: pre-transpile (pure) // --------------------------------------------------------------------------- export interface PrepareXmlResult { @@ -257,7 +256,7 @@ export function prepareXmlForLibraryBuild(project: PLCProject, manifestJson: str } // --------------------------------------------------------------------------- -// Stage 2: post-xml2st (pure) +// Stage 2: post-transpile (pure) // --------------------------------------------------------------------------- export interface LibraryBuildResult { @@ -337,7 +336,7 @@ export interface LibraryBuildAux { } /** - * Stage 2. Given xml2st's monolithic `program.st`, the POU + * Stage 2. Given the transpiler's monolithic `program.st`, the POU * inventory from Stage 1, and the parsed manifest: split program.st * per-POU, drop the stub, hand the remaining sources to strucpp's * compileStlib. @@ -369,7 +368,7 @@ export function libraryBuildFromTranspiledSt( // // - The stub program's `.st` file (the library doesn't ship // the stub). - // - `_config.st` (xml2st's CONFIGURATION block references the + // - `_config.st` (the transpiler's CONFIGURATION block references the // stub program, which we've just removed — leaving it in // causes strucpp to emit "Unknown program type 'MAIN'" // diagnostics). Libraries don't carry configurations diff --git a/src/backend/shared/library/program-build-helpers.ts b/src/backend/shared/library/program-build-helpers.ts index 84ad74fd2..0a03a0e56 100644 --- a/src/backend/shared/library/program-build-helpers.ts +++ b/src/backend/shared/library/program-build-helpers.ts @@ -119,7 +119,7 @@ export function enrichErrorWithPouContext( if (/^\s*END_VAR\b/i.test(lines[i])) lastEndVar = i + 1 // 1-indexed } // Body starts after the last END_VAR, but the ST generator - // (`pou-text-serializer.ts` and xml2st on the compile path) + // (`pou-text-serializer.ts` and the ST transpiler on the compile path) // inserts blank separator lines between END_VAR and the body // content. Those blank lines exist in the per-POU file the // splitter handed strucpp but NOT in `pou.body.value`, which is diff --git a/src/backend/shared/library/program-build-pipeline.ts b/src/backend/shared/library/program-build-pipeline.ts index d72429616..4b2e554b8 100644 --- a/src/backend/shared/library/program-build-pipeline.ts +++ b/src/backend/shared/library/program-build-pipeline.ts @@ -28,7 +28,7 @@ * pre-computes the hash and passes it in; strucpp embeds it * into the debug map for stale-layout detection. * - * - No external-process orchestration — `xml2st` (XML→ST) and + * - No external-process orchestration — the ST transpiler and * `arduino-cli` (firmware compile) stay in the platform-specific * orchestrator that wraps this pipeline. This module is purely * about the strucpp invocation slice. diff --git a/src/backend/shared/transpilers/st-transpiler/core/path-tree.ts b/src/backend/shared/transpilers/st-transpiler/core/path-tree.ts index 09c1535ca..a56be025a 100644 --- a/src/backend/shared/transpilers/st-transpiler/core/path-tree.ts +++ b/src/backend/shared/transpilers/st-transpiler/core/path-tree.ts @@ -41,7 +41,7 @@ export function leafNode(chunks: ProgramChunk[]): PathNode { /** * Stable structural key for a PathNode — used by `factorizePaths` to * detect common terms. Identical to the Python `repr` output the - * original xml2st pipeline keys on. + * original PLCopen pipeline keys on. */ export function pythonReprNode(node: PathNode): string { switch (node.kind) { diff --git a/src/backend/shared/transpilers/st-transpiler/emit/pou-graphical.ts b/src/backend/shared/transpilers/st-transpiler/emit/pou-graphical.ts index 101d34a41..1f2ab278a 100644 --- a/src/backend/shared/transpilers/st-transpiler/emit/pou-graphical.ts +++ b/src/backend/shared/transpilers/st-transpiler/emit/pou-graphical.ts @@ -101,7 +101,7 @@ export function generateGraphicalPou(pou: TranspilePou, project: TranspileProjec /* ────────────────────────── helpers ─────────────────────────────────────── */ // Block signatures from every graphical block instance's variant — the -// co-located equivalent of xml2st's embedded payload. Deduped +// co-located equivalent of the embedded payload. Deduped // by name, first instance wins — deliberately mirroring the oracle's // dedup; user POUs are excluded (they resolve from their // own interface). diff --git a/src/backend/shared/transpilers/st-transpiler/helpers/block-library.ts b/src/backend/shared/transpilers/st-transpiler/helpers/block-library.ts index ce485b1d6..537f5b920 100644 --- a/src/backend/shared/transpilers/st-transpiler/helpers/block-library.ts +++ b/src/backend/shared/transpilers/st-transpiler/helpers/block-library.ts @@ -34,7 +34,7 @@ export function isRecord(v: unknown): v is Record { /** * Build a block signature from a placed block's `node.data.variant`. * - * Mirrors `collect-library-blocks.ts` / xml2st's `_pou_to_block_infos`: + * Mirrors `collect-library-blocks.ts`'s block-info derivation: * EN/ENO are implicit control pins (dropped); inOut params appear on both * sides; a function's return is already a class-`output` variable named `OUT`. * Generic IEC meta-types (`ANY`, `ANY_NUM`, …) are kept verbatim and resolved diff --git a/src/backend/shared/transpilers/st-transpiler/walker/ld.ts b/src/backend/shared/transpilers/st-transpiler/walker/ld.ts index 76aa1807d..57669b916 100644 --- a/src/backend/shared/transpilers/st-transpiler/walker/ld.ts +++ b/src/backend/shared/transpilers/st-transpiler/walker/ld.ts @@ -3,7 +3,7 @@ * * Walks `RFBody.rungs[*].nodes/edges` directly — no PLCOpen * intermediate. Output must match the python oracle - * (`xml2st.py --keep-structs --no-complex-parser`) byte-for-byte; + * byte-for-byte against the python oracle; * `tests/per_case.test.ts` is the per-case validation loop, and * `tests/golden_react_flow.test.ts` covers the larger harvested * corpus once it lands. diff --git a/src/backend/shared/utils/PLC/__tests__/collect-library-blocks.test.ts b/src/backend/shared/utils/PLC/__tests__/collect-library-blocks.test.ts index a6949a688..879f64f49 100644 --- a/src/backend/shared/utils/PLC/__tests__/collect-library-blocks.test.ts +++ b/src/backend/shared/utils/PLC/__tests__/collect-library-blocks.test.ts @@ -1,6 +1,6 @@ /** * Tests for collectLibraryBlocks — the pure project→ collector that - * embeds used library-block signatures for the xml2st transpiler. + * embeds used library-block signatures. */ import type { PLCProjectData } from '@root/middleware/shared/ports/open-plc-types' @@ -75,7 +75,7 @@ describe('collectLibraryBlocks', () => { ]) const result = collectLibraryBlocks(project) as any - expect(result.data['@name']).toBe('openplc.org/xml2st/library-blocks') + expect(result.data['@name']).toBe('openplc.org/library-blocks') const pous = result.data.libraryBlocks.pou expect(pous).toHaveLength(1) expect(pous[0]).toMatchObject({ diff --git a/src/backend/shared/utils/PLC/__tests__/split-program-st.test.ts b/src/backend/shared/utils/PLC/__tests__/split-program-st.test.ts index 14e2af57f..bc64d7aaf 100644 --- a/src/backend/shared/utils/PLC/__tests__/split-program-st.test.ts +++ b/src/backend/shared/utils/PLC/__tests__/split-program-st.test.ts @@ -49,8 +49,8 @@ describe('splitProgramSt', () => { expect(result!.files.get('Main.st')).toBe(source) }) - it('matches POU names case-insensitively (xml2st may upper-case)', () => { - // The editor's project model has the user-typed casing; xml2st + it('matches POU names case-insensitively (the transpiler may upper-case)', () => { + // The editor's project model has the user-typed casing; the transpiler // sometimes upper-cases identifiers. The splitter must handle // either direction. const source = 'PROGRAM MAIN\n VAR x : INT; END_VAR\n x := 1;\nEND_PROGRAM\n' @@ -186,7 +186,7 @@ describe('splitProgramSt', () => { expect(result!.files.has('State_Display.st')).toBe(false) }) - it('emits `.st` for ST and graphical POUs (xml2st renders them as ST)', () => { + it('emits `.st` for ST and graphical POUs (the transpiler renders them as ST)', () => { const source = 'PROGRAM Main_LD\n VAR x : INT; END_VAR\n x := 1;\nEND_PROGRAM\n' + 'PROGRAM Main_ST\n VAR y : INT; END_VAR\n y := 2;\nEND_PROGRAM\n' @@ -243,9 +243,9 @@ describe('splitProgramSt', () => { }) }) - describe('realistic xml2st-shaped output', () => { + describe('realistic transpiler-shaped output', () => { it('handles a multi-POU + TYPE + CONFIGURATION program', () => { - // Mimics the shape xml2st emits for a typical project. + // Mimics the shape the transpiler emits for a typical project. const source = `TYPE TrafficState : (RED, YELLOW, GREEN); END_TYPE diff --git a/src/backend/shared/utils/PLC/collect-library-blocks.ts b/src/backend/shared/utils/PLC/collect-library-blocks.ts index 13dbe2ff6..e204ca496 100644 --- a/src/backend/shared/utils/PLC/collect-library-blocks.ts +++ b/src/backend/shared/utils/PLC/collect-library-blocks.ts @@ -2,15 +2,15 @@ import type { PLCProjectData } from '@root/middleware/shared/ports/open-plc-type /** * Collect the signatures of every *library* block a project uses and emit them - * as a PLCopen `` payload that the xml2st transpiler reads. + * as a PLCopen `` payload embedded in the exported project XML. * - * Why: xml2st emits a local temporary per FUNCTION output and must declare it - * with a concrete type. It infers that type from the wired connections, but - * cannot when a function has no typed pin to borrow from (e.g. a nullary - * `CURRENT_DT` whose output is unconnected) — it then falls back to the illegal - * type `ANY`, which STruC++ rejects. Rather than make xml2st carry a block - * library (which would diverge from the real STruC++ library), we hand it the - * exact signatures the project uses, embedded in the project file itself. + * Why: an ST generator emits a local temporary per FUNCTION output and must + * declare it with a concrete type. It infers that type from the wired + * connections, but cannot when a function has no typed pin to borrow from + * (e.g. a nullary `CURRENT_DT` whose output is unconnected) — it would then + * fall back to the illegal type `ANY`, which STruC++ rejects. Embedding the + * exact signatures the project uses avoids carrying a separate block library + * that could diverge from the real STruC++ library. * * Every graphical block instance already carries its full typed signature in * `node.data.variant` (the editor stamps it from the library on placement), so @@ -19,10 +19,10 @@ import type { PLCProjectData } from '@root/middleware/shared/ports/open-plc-type * identical across the desktop and web builds. * * Output shape feeds xmlbuilder2 (see XmlGenerator); it is inserted as - * `/` after ``. Contract: xml2st/docs/library-blocks.md. + * `/` after ``. */ -const DATA_NAME = 'openplc.org/xml2st/library-blocks' +const DATA_NAME = 'openplc.org/library-blocks' type XmlElement = Record @@ -41,7 +41,7 @@ type BlockVariant = { variables: VariantVariable[] } -/** ``, ``, ... — xml2st reads the (upper-cased) tag name. */ +/** ``, ``, ... — the consumer reads the (upper-cased) tag name. */ const typeElement = (variable: VariantVariable): XmlElement => ({ [variable.type.value]: '' }) const variableElement = (variable: VariantVariable): XmlElement => ({ @@ -78,7 +78,7 @@ const collectBlockVariants = (project: PLCProjectData): BlockVariant[] => { const variantToPou = (variant: BlockVariant): XmlElement => { const isFunctionBlock = variant.type === 'function-block' - // EN/ENO are implicit control pins; xml2st adds them itself. + // EN/ENO are implicit control pins; the ST generator adds them itself. const vars = variant.variables.filter((v) => v.name !== 'EN' && v.name !== 'ENO') const inputs = vars.filter((v) => v.class === 'input') const inouts = vars.filter((v) => v.class === 'inOut') @@ -113,7 +113,7 @@ const variantToPou = (variant: BlockVariant): XmlElement => { * project references no library blocks (e.g. text-only POUs). * * User-defined POUs are excluded: their definitions already travel in - * `` and xml2st resolves them directly. + * `` and the generator resolves them directly. */ export const collectLibraryBlocks = (project: PLCProjectData): XmlElement | null => { const userPouNames = new Set(project.pous.map((pou) => pou.data?.name)) diff --git a/src/backend/shared/utils/PLC/split-program-st.ts b/src/backend/shared/utils/PLC/split-program-st.ts index eb5f9bf54..b282bf054 100644 --- a/src/backend/shared/utils/PLC/split-program-st.ts +++ b/src/backend/shared/utils/PLC/split-program-st.ts @@ -1,14 +1,14 @@ /** - * Split the monolithic `program.st` produced by xml2st into one + * Split the monolithic `program.st` produced by the ST transpiler into one * synthetic source file per POU, plus auxiliary files for the project- * level sections (`_types.st`, `_globals.st`, `_config.st`). The * editor feeds the result to strucpp via `additionalSources`, so error * reports come back with `error.file === '.st'` instead of a * generic `program.st` line. * - * Why post-process here instead of changing xml2st: xml2st is being - * abandoned, and Runtime v3 (MatIEC era) ingests the monolithic - * `program.st` verbatim — splitting upstream would break that target. + * Why post-process here rather than upstream: Runtime v3 (MatIEC era) + * ingests the monolithic `program.st` verbatim — splitting upstream + * would break that target. * The editor already knows the project's POU list (it produced the XML * the splitter consumes), so the operation is name-anchored and * deterministic, not a generic ST parse. @@ -22,7 +22,7 @@ export interface KnownPou { /** POU name as the user knows it. Strucpp uppercases internally; we - * match case-insensitively against xml2st output. */ + * match case-insensitively against the transpiler output. */ name: string kind: 'PROGRAM' | 'FUNCTION' | 'FUNCTION_BLOCK' /** @@ -62,7 +62,7 @@ interface RangeMatch { * Find the line index (1-indexed, inclusive) where a POU header for * `(name, kind)` starts in `lines`. Returns -1 when no match is found. * - * The header pattern is intentionally tight: xml2st always emits the + * The header pattern is intentionally tight: the transpiler always emits the * keyword at column 0 followed by the POU name and either a colon * (functions return-type), whitespace, or end-of-line. This rules out * matches on identifiers that contain the POU name as a substring diff --git a/src/backend/shared/utils/PLC/xml-generator.ts b/src/backend/shared/utils/PLC/xml-generator.ts index 211b0c794..a9c3e573a 100644 --- a/src/backend/shared/utils/PLC/xml-generator.ts +++ b/src/backend/shared/utils/PLC/xml-generator.ts @@ -71,7 +71,7 @@ const XmlGenerator = ( } /** - * Embed the signatures of every library block the project uses, so xml2st + * Embed the signatures of every library block the project uses, so an ST generator * can type the temporaries it generates for FUNCTION outputs without * carrying a block library of its own. Added last so it serialises after * , as the PLCopen schema requires for . diff --git a/src/frontend/components/_atoms/graphical-editor/autocomplete/index.tsx b/src/frontend/components/_atoms/graphical-editor/autocomplete/index.tsx index 5a2400ccc..0ff9b9174 100644 --- a/src/frontend/components/_atoms/graphical-editor/autocomplete/index.tsx +++ b/src/frontend/components/_atoms/graphical-editor/autocomplete/index.tsx @@ -230,7 +230,13 @@ export const GraphicalEditorAutocomplete = forwardRef {selectableValues.length > 0 && ( {variables && variables.length > 0 && ( <> -
-
+
+ {/* `scrollbar-gutter: stable` reserves the scrollbar's + width so the content-based auto-size accounts for it — + otherwise, when the list overflows and the scrollbar + appears, it steals horizontal space and the widest name + wraps its last character. */} +
{variables.map((variable) => (
- {variable.name} + {variable.name}
))}
@@ -288,7 +311,7 @@ export const GraphicalEditorAutocomplete = forwardRef
{ body: { language: 'fbd', value: {} as never }, }) const result = serializePouSignatureToST(pou) - // Block keywords carry the xml2st-parity 2-space indent. + // Block keywords carry the legacy-parity 2-space indent. expect(result).toContain(' VAR\n END_VAR') }) diff --git a/src/frontend/utils/PLC/xml-generator/base-type-tag.ts b/src/frontend/utils/PLC/xml-generator/base-type-tag.ts index a54653704..cfc8a18a9 100644 --- a/src/frontend/utils/PLC/xml-generator/base-type-tag.ts +++ b/src/frontend/utils/PLC/xml-generator/base-type-tag.ts @@ -6,7 +6,7 @@ import { lookupBaseType } from '../../iec-types-registry' * For PLCopen TC6 elementaryTypes (closed `` in the XSD), use * the canonical XML element name from strucpp's iec-types registry — * mixed-case on purpose: `` / `` are lowercase, - * everything else uppercase. xml2st (MatIEC's TC6 schema validator) + * everything else uppercase. MatIEC's TC6 schema validator * rejects `` outright with the same "expected one of (BOOL, * BYTE, ...)" error users see when a case is wrong. * diff --git a/src/frontend/utils/PLC/xml-generator/codesys/__tests__/data-type-xml.test.ts b/src/frontend/utils/PLC/xml-generator/codesys/__tests__/data-type-xml.test.ts index f982cfbb2..f90b6bb47 100644 --- a/src/frontend/utils/PLC/xml-generator/codesys/__tests__/data-type-xml.test.ts +++ b/src/frontend/utils/PLC/xml-generator/codesys/__tests__/data-type-xml.test.ts @@ -377,7 +377,7 @@ describe('codeSysParseDataTypesToXML', () => { // `initialValue: { simpleValue: { value: '' } }` wrapper instead // of `undefined`. The XML emitter must treat the empty inner // value the same as absence — otherwise it emits - // `` which xml2st turns into a stray `:= ` + // `` which the ST generator turns into a stray `:= ` // in the ST output, breaking compilation. it('omits initialValue for an array struct variable whose inner value is empty', () => { const xml = makeBaseXml() diff --git a/src/frontend/utils/PLC/xml-generator/old-editor/__tests__/data-type-xml.test.ts b/src/frontend/utils/PLC/xml-generator/old-editor/__tests__/data-type-xml.test.ts index bc7110171..b228f3de2 100644 --- a/src/frontend/utils/PLC/xml-generator/old-editor/__tests__/data-type-xml.test.ts +++ b/src/frontend/utils/PLC/xml-generator/old-editor/__tests__/data-type-xml.test.ts @@ -338,7 +338,7 @@ describe('oldEditorParseDataTypesToXML', () => { // Regression: struct creation seeds new variables with an // `initialValue: { simpleValue: { value: '' } }` wrapper instead // of `undefined`. The XML emitter must treat the empty inner - // value the same as absence — otherwise xml2st turns it into + // value the same as absence — otherwise the ST generator turns it into // a stray `:= ` in the ST output and breaks compilation. it('omits initialValue for an array struct variable whose inner value is empty', () => { const xml = makeBaseXml() diff --git a/src/frontend/utils/PLC/xml-generator/old-editor/__tests__/type-xml.test.ts b/src/frontend/utils/PLC/xml-generator/old-editor/__tests__/type-xml.test.ts index 10790213c..fcfaeb5c2 100644 --- a/src/frontend/utils/PLC/xml-generator/old-editor/__tests__/type-xml.test.ts +++ b/src/frontend/utils/PLC/xml-generator/old-editor/__tests__/type-xml.test.ts @@ -16,7 +16,7 @@ describe('convertTypeToXml', () => { // Regression: project data canonicalizes base types to uppercase // (baseTypes constant emits 'STRING'). The xml emitter must still - // produce — xml2st rejects outright. + // produce — STruC++ rejects outright. it('converts uppercase STRING base-type to lowercase tag', () => { const result = convertTypeToXml({ definition: 'base-type', value: 'STRING' }) expect(result).toEqual({ string: '' }) diff --git a/src/frontend/utils/__tests__/generate-iec-variables-to-string.test.ts b/src/frontend/utils/__tests__/generate-iec-variables-to-string.test.ts index d281437c5..9c4ef4d29 100644 --- a/src/frontend/utils/__tests__/generate-iec-variables-to-string.test.ts +++ b/src/frontend/utils/__tests__/generate-iec-variables-to-string.test.ts @@ -11,7 +11,7 @@ const makeVariable = (overrides: Partial & Pick { expect(result.split('VAR_INPUT').length).toBe(2) // one occurrence = 2 parts }) - it('emits consecutive var-class blocks with no blank line between them (xml2st parity)', () => { - // xml2st walks `self.Interface` and emits each var-class block + it('emits consecutive var-class blocks with no blank line between them (legacy parity)', () => { + // the legacy generator walks `self.Interface` and emits each var-class block // back-to-back, immediately closing one END_VAR before opening the // next header. The vars-text editor needs to mirror that exactly // so a manual edit of the text view doesn't get re-formatted into diff --git a/src/frontend/utils/debugger-session.ts b/src/frontend/utils/debugger-session.ts index d77fa1a4d..505a7f486 100644 --- a/src/frontend/utils/debugger-session.ts +++ b/src/frontend/utils/debugger-session.ts @@ -29,7 +29,7 @@ import { buildDebugPathPrefix, findInstanceName, type PLCInstanceMapping } from * * Plain progress messages get split on newlines into one log entry * per line — keeps the existing scroll/wrap/copy behaviour intact for - * the long Arduino-CLI / xml2st outputs. + * the long Arduino-CLI / compiler outputs. * * Events that carry a structured `compileError` are emitted as a * single multi-line entry instead, with the structured field attached. diff --git a/src/frontend/utils/generate-iec-variables-to-string.ts b/src/frontend/utils/generate-iec-variables-to-string.ts index 24fa192a9..3463bb43c 100644 --- a/src/frontend/utils/generate-iec-variables-to-string.ts +++ b/src/frontend/utils/generate-iec-variables-to-string.ts @@ -10,8 +10,8 @@ const classToVarBlock: Record = { temp: 'VAR_TEMP', } -// Indentation mirrors xml2st's `PLCGenerator.PouProgramGenerator.GenerateProgram` -// output (see `~/Documents/Code/xml2st/PLCGenerator.py:2414-2478`): two +// Indentation mirrors the legacy PLCGenerator's `PouProgramGenerator.GenerateProgram` +// output: two // spaces before the var-block keywords, four spaces before each // declaration line. Matching that format keeps the editor's // variables-text view byte-identical to the per-POU `.st` file the @@ -72,7 +72,7 @@ export const generateIecVariablesToString = (variables: PLCVariable[]): string = textualDeclaration += line + '\n' }) - // xml2st emits consecutive var-class blocks back-to-back with no + // the legacy generator emits consecutive var-class blocks back-to-back with no // blank line between them — ` END_VAR\n VAR_INPUT\n...`. Drop // the prior `END_VAR\n\n` that left a separator behind. textualDeclaration += `${VAR_BLOCK_INDENT}END_VAR\n` diff --git a/src/frontend/utils/iec-types-registry.ts b/src/frontend/utils/iec-types-registry.ts index 0868eb0fd..30574982d 100644 --- a/src/frontend/utils/iec-types-registry.ts +++ b/src/frontend/utils/iec-types-registry.ts @@ -138,7 +138,7 @@ const XML_ELEMENT_INDEX: ReadonlyMap = (() => { * IEC type metadata. Case-sensitive — unlike `lookupBaseType`, callers here * already have the exact tag fast-xml-parser handed them, and PLCopen XML * element names are case-significant (`` vs `` are not - * interchangeable — xml2st rejects the latter). + * interchangeable — STruC++ rejects the latter). */ export function lookupBaseTypeByXmlElement(elementName: string): IECTypeMetadata | undefined { return XML_ELEMENT_INDEX.get(elementName) diff --git a/src/middleware/shared/ports/compiler-port.ts b/src/middleware/shared/ports/compiler-port.ts index d1af6230a..375cbe618 100644 --- a/src/middleware/shared/ports/compiler-port.ts +++ b/src/middleware/shared/ports/compiler-port.ts @@ -1,7 +1,7 @@ /** * CompilerPort — Abstracts the PLC compilation pipeline. * - * Editor adapter: Delegates to main process via IPC (local tools: xml2st, STruC++, arduino-cli). + * Editor adapter: Delegates to main process via IPC (local tools: STruC++, arduino-cli). * Web adapter: Delegates to remote API at compile.getedge.me (callGenerateSt, callCompileSt, etc.). * * The UI only knows "compile this project" and receives progress events. @@ -80,7 +80,7 @@ export interface CompileLibraryArgs { /** * Skip the verification-result cache for this run. The MD5 cache * normally short-circuits the slow simulator-target verification - * when the program.st coming out of xml2st hasn't changed since + * when the program.st coming out of the ST transpiler hasn't changed since * the last successful (or failed) verify; `cleanBuild: true` * forces a fresh compile. * @@ -115,7 +115,7 @@ export interface CompilerPort { /** * Build a `.stlib` archive from a Library Project on disk. - * Editor: validates the manifest, runs the local xml2st binary, + * Editor: validates the manifest, runs the in-process ST transpiler, * pipes the result through strucpp's library compiler, and * writes the archive to `/build/.stlib`. * Web (future): posts the project + manifest to a remote service diff --git a/src/middleware/shared/utils/library/compose-runtime-v4-bundle.ts b/src/middleware/shared/utils/library/compose-runtime-v4-bundle.ts index bb8942c5b..310d83d18 100644 --- a/src/middleware/shared/utils/library/compose-runtime-v4-bundle.ts +++ b/src/middleware/shared/utils/library/compose-runtime-v4-bundle.ts @@ -45,7 +45,7 @@ */ export interface ComposeRuntimeV4BundleInput { - /** Concatenated ST program emitted by xml2st. */ + /** Concatenated ST program emitted by the ST transpiler. */ programSt: string /** MD5 of `programSt` — written to `defines.h` so the v4 runtime * shim (`runtime_v4_entry.cpp`) can report it via FC 0x45. */ @@ -100,7 +100,7 @@ export interface ComposeRuntimeV4BundleInput { export function composeRuntimeV4Bundle(input: ComposeRuntimeV4BundleInput): Record { const files: Record = {} - // 1. Concatenated ST program (xml2st output) + // 1. Concatenated ST program (ST transpiler output) files['program.st'] = input.programSt // 2. Strucpp emitted artefacts at the zip root