Repository navigation
A FunctionElement rename carries into the interface dictionary's catalog, in both editors - #67
Merged
Merged
Conversation
Renaming a function of a service interface now renames System Composer's copy of it too (p_Name and p_FunctionPrototype in the interface dictionary), in text and binary dictionaries, as one undo step (ruling A5). Core's own save already does this (data-explorer-core #109), but neither editor saves through core, and catalogRenameOf only passes a rename of the entry itself, so the catalog kept the old name. - scRename.ts: a second gate, catalogFunctionRenameOf (a Name edit of a Simulink.FunctionElement directly under the top-level entry, read before the mutation), and two format helpers over core's scanScJsonFunctions / scanScXmlFunctions and scFunctionRenameEdits. - Each provider takes one more branch in its scEdits / scPart expression. The text editor puts the catalog ranges in the same WorkspaceEdit. The binary editor's member swap rides pushEdit, whose undo restores the member's original bytes. - A rename the Prototype cannot follow is refused by core before any catalog edit is computed, and shows as a validationError like every other refused edit. Tests: scRenameCarry.test.ts runs each scenario (one rename, interface renamed before or after, chain, rename back, swap) through the provider's composition and through core's own serializeSource, in both formats, and requires the same catalog. archRenameCarry.test.ts adds a save test and an undo test on a new fixture, arch_service_binary.sldd. This needs the barrel exports on data-explorer-core's export-function-rename-catalog-carry branch. The pin moves to the core release that carries them in a separate change.
data-explorer-core v1.39.0 (mathworks/data-explorer-core#119, released in #120 there) exports scFunctionRenameEdits, scanScJsonFunctions, scanScXmlFunctions and the ScFunction and CatalogFunctionRenames types from its barrel, which the previous commit calls to carry a FunctionElement rename into the System Composer catalog. The lockfile changes only core's entries: the root dependency spec and node_modules/data-explorer-core, now 1.39.0 resolved at 8e334082682eae7901cc07016f4fb90b3cdc7c73.
scRenameCarry.test.ts and archRenameCarry.test.ts compose the edit from the scRename helpers themselves, so neither reaches the providers' edit handler: with SlddTextEditorProvider.ts and BinarySlddEditorProvider.ts put back to main, all 44 unit and 5 integration tests there stay green. This file sends the table's own `edit` message through each real provider and a fake panel, and grades what the provider wrote against core's serializeSource of the same renames: one rename (p_Name and p_FunctionPrototype move, and nothing else), the interface renamed first, a chain, a function the catalog does not list, a Prototype that cannot follow (refused with core's own reason, nothing written), and undo as one step (text: the one change event's inverse gives back the original bytes; binary: the member read from the file, byte for byte). With only SlddTextEditorProvider.ts reverted to main, 4 of the 6 text cases fail and the 6 binary cases pass; with only BinarySlddEditorProvider.ts reverted, 4 of the 6 binary cases fail and the 6 text cases pass. The 2 that pass in each are the controls (the unlisted function and the refusal), which write no catalog edit on main either.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The maintainer's ruling A5: "a FunctionElement rename also renames the System Composer interface dictionary's copy (p_Name / p_FunctionPrototype), through the existing catalog-rename code, in both formats."
What was wrong
Renaming a
Simulink.FunctionElement(a function of a service interface) changed the data part only. Core's own save carries that rename into the catalog (mathworks/data-explorer-core#109), but neither editor saves through core: each one carries renames into the catalog itself, andcatalogRenameOfonly lets through a rename of a top-level entry. So a function rename left the catalog'sp_Nameandp_FunctionPrototypeat the old name, and when the file was reopened MATLAB found the interface dictionary and the data part disagreeing about the function's name.The fix
src/host/scRename.tsadds a second gate,catalogFunctionRenameOf. It matches a Name edit of aSimulink.FunctionElementdirectly under the top-level entry, and it is read before the mutation, sonode.nameis still the name the file has. It never fires together withcatalogRenameOf, because that one needs the row to be the entry and this one needs a function directly under it. Two format helpers then run core's own function edits (scFunctionRenameEditsoverscanScJsonFunctions/scanScXmlFunctions), the same ones core's save applies. Each provider gains one branch in its existingscEdits/scPartexpression.SlddTextEditorProvider): the catalog ranges go into the sameWorkspaceEditas the entry-span edit, so the rename is one undo step.BinarySlddEditorProvider): the catalog is a zip member the editor only passes through, so the carry is a member swap.scXmlFunctionRenamePatchhas the same shape asscXmlRenamePatchand goes throughpushEdit, whose undo restores the member's original bytes exactly.If the catalog does not list the function, there are no extra ranges and no patch.
Refused when the Prototype cannot follow
Core refuses a function rename that its Prototype cannot follow (mathworks/data-explorer-core#104) with
'f' cannot be renamed: its Prototype '...' does not declare the function 'f' in the form [outputs =] f(inputs), so the Prototype cannot be renamed with it, and MATLAB requires the two to match.It also refuses a sibling's name. Both refusals happen insetProperty, before any catalog edit is computed, and appear as the samevalidationErroras any other refused edit. Nothing is written: the text is unchanged, and in binary the member is the same object and the chunk is unchanged.Tests
test/scRenameCarry.test.ts, 31 new tests:fandg's argumentgare left as read.createSession/ingest/serializeSource, and the two catalogs must be identical. Scenarios: one rename, interface renamed before, interface renamed after, a chain, a rename back, and (text only) a swap through a temporary name.toBe(part.before), and the member surviving the save's re-zip.test-integration/suite/archRenameCarry.test.ts, 2 new tests: a save writes the function renamed in the chunk and in the catalog, at exactly the two sites. Undo restores the member byte for byte, redo swaps it back, and a save after undo writes the original.test-integration/suite/functionRenameThroughEditors.test.ts, 12 new tests, 6 per editor. These go through the real providers. Each one sends theeditmessage the table sends (columnId: 'Name', with the row id taken from the rows the provider painted) through a fake panel (tools/hostHarness.ts'sfakePanel). It then checks what the provider wrote against core's ownserializeSourceof the same renames. The cases, in each editor:p_Nameandp_FunctionPrototype, and the saved catalog equals core's;validationErrorwhose reason equals core's own, and nothing written (in text, the document is not dirty);applyEdit, gives back the original bytes. Binary: one edit, whoseundo()restores the chunk and the member read from the file, and a save then writes that member byte for byte.test/fixtures/arch_service_binary.sldd, made bymake-fixtures.mjs.arch_binary.slddcould not be reused: it has no service interface, and other suites count its entries. The new fixture holdsServiceInterfacewithf: y = f(u)andg: [a,b] = g(g), the shape of core'sfunctionElementRename.test.ts(example/dd1.sldd). It has two traps: a data interface also namedf, andg's first argument, namedg. Running the generator rewrites the other zip fixtures' mtimes, so only the new file is committed.Fail-before. I stubbed the three helpers to main's behaviour (the gate returns null, no edits, no patch) without committing the stub. Then:
y = compute(u)/<p_Name>computeand the stub leavesy = f(u)/<p_Name>f. The other 3 fail with a TypeError on a null part rather than at a content assertion (Cannot read properties of null (reading 'after')twice, and'before'once). These are the binary tests "leaves the data interface named f…", "survives the re-zip…" and "puts both surfaces back on undo…".archRenameCarrytests fail, and 8 of the 12 provider-level tests fail.The other 14 new tests pass on main as well, which is right for guards: the 5 negative gate cases, rename back in both formats, the re-read check, the 4 refusals (core already refuses), and the 2 no-patch cases. The file's 13 existing tests stay green.
Fail with a provider reverted. The tests above pin the helpers, but they do not pin the branch each provider adds.
scRenameCarry.test.tsandarchRenameCarry.test.tscompose the edit from the helpers themselves, so with both providers put back toorigin/main(and this PR'sscRename.tskept), all 44 tests inscRenameCarryand all 5 inarchRenameCarrystay green.functionRenameThroughEditors.test.tscloses that gap. I put one provider back at a time withgit show origin/main:<path> > <path>and restored it after, without committing the revert:SlddTextEditorProvider.tsreverted: 4 of the 6 text cases fail (one rename, interface first, chain, undo). All 6 binary cases pass.BinarySlddEditorProvider.tsreverted: the same 4 of the 6 binary cases fail. All 6 text cases pass.The 2 cases that pass in each editor are the controls, the unlisted function and the refusal, because on main they write no catalog edit either.
Core pin
data-explorer-coremoves from#v1.38.1to#v1.39.0(tag on8e33408, mathworks/data-explorer-core#120). That release exports the carry from the barrel (mathworks/data-explorer-core#119):scFunctionRenameEdits,scanScJsonFunctions,scanScXmlFunctions,ScFunction,CatalogFunctionRenames. In the lockfile, only core's two entries change. There is no CHANGELOG change; that is added at release.Gates (at
ffe323b, core v1.39.0)npm run verify: rc 0. vitest ran 169 files with 3,264 passed (3,233 on main, +31).check:leakOK, with all 646 lockfile resolutions public.npm run test:integration: 191 passing, 1 pending (179 atcb72803, +12). The pending test iscutPasteUndo's same-document move, which skips itself on a host that does not apply undo (undoAvailable). It has nothing to do with this change and it runs on CI.ffe323b: all 4 checks pass.build-test's integration run has 192 passing, withcutPasteUndo's move running there, and it includes both new suites.Finishes the maintainer's A5 ruling (core #109, #119).