Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions changelog.d/reg-reader.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
### Added — `--for` table rows: a write into a registry with a computed key, and the reads of that registry

A `shape="table"` site can now be a write into a table with a computed key: `storage[resource+"/log"] = podStorage.Log` in Go, `handlers[name + "_svc"] = handler` in Python, ``table[`/api/${ver}`] = route`` in TypeScript. The row is listed when the hit is the key or the value of that one statement (not the table's own name, and not a later statement on the line) and the enclosing function is named `New*`, `new_*`, `Register*` or `register_*` (an `async_` prefix aside). The name is the evidence, not proof. Such a row carries `reg=` with the table and key up to the `=`, and it is a strong row, so a task with no table or registration word lists it too. A literal key (`storage["pods"] = x`, `handlers[0x10] = f`, `handlers[1_000] = f`) is left to the table rule as before, and so are a comparison (`storage[k] == x`), a line of a multi-line string that looks like a write, and a write in a function with any other name.

When the answer above the block already names that table, the element also lists `<lr>` rows: reads of the table in the row's file and in the files of the function's callers. A read is `t[k]` that is not the left side of an `=`, or `t.get(`, in code: a read inside a comment or a string is not counted. Each read on a line counts. A local bound to the function's call (`s := p.NewRESTStorage()`, `const routes = registerRoutes(...)`) counts as the same table, in the row's own file as in a caller's; the call has to be the value itself, so `s := choose(p.NewRESTStorage())` binds nothing. Reads whose key shares a quoted part of the written key come first, and at most 2 are listed. `readers=` counts all the reads found. It is a floor, with `floor="1"`, when a file could not be read, when callers in more than 16 files were not read, or when no call graph was there to find them. When the `<lr>` rows would push the element past the table's byte cap they are left out, and `readers=` still counts every read. A read of a same-named table in a file that does not call the function is not listed. Where the answer does not name the table, there are no `<lr>` rows and the element is unchanged. A legend sentence rides only with a subscript row. Gate: `test/forregrowcheck.sh` (the subscript-write and table-reader arms).
2 changes: 2 additions & 0 deletions docs/LIMITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,8 @@ Discloses: `capped`, `lit_capped`
| `kForTableContextRows` | `4` | — | shape=table: table rows served with the lines after them |
| `kForTableMaxAnchor` | `60` | — | a longer backticked span is no anchor |
| `kForTableRankedRows` | `4096` | — | shape=table: source sites read for a table row and ordered (a registry past the readers in path order must still rank first) |
| `kForTableReaderFiles` | `16` | — | REG-READER: caller files read for them, by path (past it: readers= is a floor) |
| `kForTableReaderRows` | `2` | — | REG-READER: <lr> reads of a subscript row's table listed (readers= counts all) |
| `kForTableRows` | `32` | — | shape=table: <ls> rows per anchor (next= lists all) |

### `src/formembers.h`
Expand Down
Loading
Loading