Skip to content

Snapshot: describe tables bound to a dereferenced data reference {/MR_X/*} - #63

Merged
oblomov-dev merged 2 commits into
mainfrom
claude/serene-fermat-xswjov
Oct 24, 2026
Merged

oblomov-dev merged 2 commits into
mainfrom
claude/serene-fermat-xswjov

Conversation

@oblomov-dev

@oblomov-dev oblomov-dev commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

abap2UI5 binds a dereferenced data reference as {/MR_X/*}, and the JSON model holds { "MR_X": { "*": [ ...rows ] } }. UI5 resolves that path without trouble, but the snapshot did not:

  • SIMPLE_PATH in lib/viewxml.mjs had no * in its character class. As a result, parseBinding("{/MR_CGUI_ALV/*}") returned { kind: 'composite', parts: [{ computed: '/MR_CGUI_ALV/*' }] }.
  • table() in lib/snapshot.mjs then noted "Table bound to something other than a model table - rows not described" and left the table out.

This showed up in abap-cloud-gui's report runtime. It binds the ALV of a table that is not a class attribute through such a reference. Because of this bug, the runtime test for zr2c_24_gridinline had to read the rows from the model directly.

Change

  • SIMPLE_PATH now accepts * as a path segment.
  • getAt (and setAt) split on / and index by key, so they already step into a * key like any other key. No change was needed there.
  • Tests in test/snapshot.test.mjs:
    • parseBinding('{/MR_X/*}') returns { kind: 'path', path: '/MR_X/*', model: '', relative: false }.
    • A sap.ui.table.Table with rows="{/MR_X/*}" over the model { MR_X: { '*': [{ A: 1 }] } } is described with one row.
  • CHANGELOG entry under Unreleased.
  • Second commit: npm audit fix, which changes only package-lock.json. The audit job was failing on advisories published after the last green main run: body-parser and zod (high), and fast-uri, hono and ip-address (moderate). The snapshot change is unrelated to these. Main would have hit the same failure at its next run.

Testing

  • With the viewxml.mjs change reverted, the two new tests fail.
  • npm test: 579 tests, 561 pass, 0 fail, 18 skipped. The skipped ones are the opt-in network tests.
  • npm audit --audit-level=high is clean, and npm run check:server-json passes.

🤖 Generated with Claude Code

https://claude.ai/code/session_016a9TXE5AZS5y7JaqHukATb

…_X/*}

SIMPLE_PATH had no * in its character class, so parseBinding classified
{/MR_X/*} as a composite and table() left the table out with "rows not
described". getAt already walks a '*' key like any other.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016a9TXE5AZS5y7JaqHukATb

Copy link
Copy Markdown
Member Author

The audit check is red for a reason outside this PR. npm audit --audit-level=high reports advisories published after the last green main run (2026-10-22): body-parser GHSA-27r3-jxmh-p828 (high) and zod GHSA-mrhx-c7xc-m3w5 (high). There are also moderates in fast-uri, hono and ip-address. This PR does not touch package.json or package-lock.json, so main will go red on the same check at its next run.

There is no fix PR yet. npm audit fix changes only package-lock.json:

  • body-parser 2.3.0 → 2.4.0
  • fast-uri 3.1.8 → 3.1.9
  • hono 4.13.9 → 4.13.13
  • ip-address 10.7.2 → 10.7.4
  • zod 4.6.5 → 4.6.7
  • one more package 6.16.0 → 6.16.1

After the fix, npm audit --audit-level=high reports 0 vulnerabilities and npm test has 561 pass, 0 fail. The lockfile bump can go into this PR or into a separate one. test passed on this head.


Generated by Claude Code

…dress moderate)

Lockfile-only bumps for advisories published after the last green main
run; the audit job failed on them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016a9TXE5AZS5y7JaqHukATb

Copy link
Copy Markdown
Member Author

Pushed the lockfile-only npm audit fix to this PR as 0924e9e. Locally, npm audit --audit-level=high now exits 0, npm test has 561 pass, 0 fail, and check:server-json passes.


Generated by Claude Code

@oblomov-dev
oblomov-dev merged commit 7732fb4 into main Oct 24, 2026
3 checks passed
@oblomov-dev
oblomov-dev deleted the claude/serene-fermat-xswjov branch October 24, 2026 11:05
oblomov-dev pushed a commit to abap2UI5-addons/abap-cloud-gui that referenced this pull request Oct 24, 2026
The agent snapshot of the mcp-server describes a table bound to a
dereferenced data reference ({/MR_X/*}) now (abap2UI5/mcp-server#63):
the grid of alv( ) is s.tables[0], its title the label. The test read
the rows from the model because the snapshot did not - and failed on
the title, which is no loose text any more.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D5BsRBuKDXbNAQvQCgVX7J
oblomov-dev added a commit to abap2UI5-addons/abap-cloud-gui that referenced this pull request Oct 24, 2026
…events, the grid stand-in (#28)

* report2cloud: the classes, interfaces and DDIC objects of the report's repository type what it reads of them

convert( { deps } ) parses them beside the report, never converts them:
an inline declaration of an event block read in another one gets the
type abaplint tells with them (DATA(lo_log) = zcl_app_factory=>...( ) is
an attribute TYPE REF TO zcl_app_log) instead of being refused.
lib/deps.mjs indexes a repository and gives what a report names, and what
that names in turn. The command line takes --deps <dir>, by default the
abapGit repository of the report (STARTING_FOLDER of its .abapgit.xml, or
its git repository); the web corpus fetches the classes, interfaces and
DDIC objects sparsely as well - 584 to 589 of 780.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D5BsRBuKDXbNAQvQCgVX7J

* report2cloud: the SAP GUI controls of a local class become the stand-ins too; no prototype names

A local class whose containers, text editors and HTML viewers have
stand-ins keeps them: its definition names the stand-ins, its methods
with controls are converted (CREATE OBJECT as NEW, the member checks).
Refused stay the controls without a stand-in and an event handler FOR
EVENT ... OF a control.

The lookup of a SAP GUI class read the object prototype for the name
constructor (METHODS constructor became 'function Object() { [native
code] }'): guiClass( ) takes the table's own entries only, and the icon
and ALV type tables have no prototype. 589 to 594 of 780.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D5BsRBuKDXbNAQvQCgVX7J

* report2cloud: the events of the SAP GUI stand-ins, a toolbar and the dialog box

SET HANDLER h->m FOR go_x of a handler FOR EVENT in a local class is
go_x->set_handler( ): the stand-in calls the method for the event of the
browser with the parameters it declares and SENDER - function_selected and
dropdown_clicked of the new z2ui5_cl_cgui_gui_toolbar (a row of buttons),
sapevent of the SAPEVENT links of the HTML viewer (action, getdata,
query_table), close of a dialog box (a title bar with Close).
Refused are FOR ALL INSTANCES, a static handler and an event a stand-in
does not raise.

The report keeps the handlers, each object once, and calls at_gui_event( )
before them - the converted report sets the instance for its local
classes there. A control that held its handler made a cycle the
transpiled serialization never leaves; that and the lost identity of an
object referenced twice are in the abap2UI5 backlog
(core-serialize-object-identity).

CREATE OBJECT x [EXPORTING ...] is NEW #( ... ) in every report now, with
the parameters of the constructor only - a call in a value kept its own.
The SAPEVENT links are found with string operations (no regex on 7.02).

New corpus report zr2c_26_events with a runtime test: the toolbar, the
links and the dialog box, opened, closed and opened again.
Web corpus: 596 of 780 (594 before).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D5BsRBuKDXbNAQvQCgVX7J

* report2cloud runtime test: read the grid of zr2c_24 from the snapshot

The agent snapshot of the mcp-server describes a table bound to a
dereferenced data reference ({/MR_X/*}) now (abap2UI5/mcp-server#63):
the grid of alv( ) is s.tables[0], its title the label. The test read
the rows from the model because the snapshot did not - and failed on
the title, which is no loose text any more.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D5BsRBuKDXbNAQvQCgVX7J

* report: the control objects and the handlers are protected attributes

No binding reaches mt_cgui_gui_obj, mt_cgui_handler and
mt_cgui_handler_obj - the abap2UI5 linter's unbound-public-attribute;
they are serialized with the app at PROTECTED as well.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D5BsRBuKDXbNAQvQCgVX7J

* report2cloud: TYPE (name) / FOR (name) of a fixed name is typed statically

PARAMETERS p TYPE ('MATNR'), SELECT-OPTIONS s FOR ('STRING') and
SELECT-OPTIONS s FOR (gv_name) with DATA gv_name ... VALUE 'VBAK-VBELN'
that nothing else names: the type is known when the class is written.
TYPE (name) becomes TYPE <type>; FOR (name) needs a data object - a
DATA <s>_type TYPE <type> goes before it. A name set at runtime (a
parameter, a variable that is assigned) stays a refusal.

Web corpus: 601 of 780 (596 before).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D5BsRBuKDXbNAQvQCgVX7J

* report2cloud: the grid of a local class is the grid stand-in z2ui5_cl_cgui_gui_alv_grid

A cl_gui_alv_grid of a local class is z2ui5_cl_cgui_gui_alv_grid, the
ALV of the report in its container (a custom control area of the dynpro,
a docking container): set_table_for_first_display( ) hands the report a
copy of the table, the field catalog, the layout and the sort (read by
the names of their fields, set_fieldcat( ) / set_layout_classic( ));
refresh_table_display( ) shows the table anew and the ALV keeps its
settings. The events go to the handlers through set_handler( ): toolbar
before the grid shows (e_object->mt_toolbar, z2ui5_cl_cgui_gui_alv_toolbar)
- its buttons are functions of the ALV and raise user_command -,
double_click and hotspot_click with the row types of the ALV. One grid
at a time; the grid of the report's global data stays alv( ).

The conversion: VALUE #( ) of a generic parameter of the grid is written
with the classic type (VALUE lvc_s_layo( )), refresh_table_display( ) is
passed the table set_table_for_first_display( ) was given in the same
class (CHANGING it_outtab = ...) - refused when it is not in reach; a
nested NEW of two controls and the components of a VALUE #( ) are no
parameters of the call; a handler body with an icon of the type pool
ICON or sender->... is converted.

The test backend transpiles DDIC table types and creates no database
table for a structure; test stubs of LVC_S_FCAT, LVC_T_FCAT, LVC_S_LAYO.
New corpus report zr2c_27_gridlocal with a runtime test: the grid in the
custom control area, the field catalog, double click, hotspot, the
function of the toolbar handler with refresh, Back.

Web corpus: 604 of 780 (601 before).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D5BsRBuKDXbNAQvQCgVX7J

* test backend: the folder layout of transpiler-cli 2.14 (@abap2ui5/node-runtime 1.148.0)

From node-runtime 1.148.0 on, the transpiler writes the project's modules
into staging/project/ and each library into a folder of its own, imported
as ../<folder>/x.mjs. The build reads the modules from there, points their
imports at the package with its own setup/own-apps.mjs, and the unit-test
runner at the flat apps/ (flatRunner of the mcp-server); before 2.14 it
stays as it was. Both runtimes run: unit 185, runtime 18 and the TODO.

The newer open-abap-core's assert_differs fails on equal values - the
label test of z2ui5_cl_cgui_select passed on the old one only because it
did not: in the transpiled runtime LAND1 has no texts and the label is
the field name. It asserts a label now, the DDIC text on a system.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D5BsRBuKDXbNAQvQCgVX7J

---------

Co-authored-by: Claude <noreply@anthropic.com>
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.

2 participants