Client: st
The Smalltalk generator expanded nested struct serialization textually:
generating the code for a struct-typed field emitted that struct's whole
reader and writer inline, at every use. There was no base case and no
visited set, so a type that contained itself expanded for ever and the
generator recursed until its own stack ran out. "thrift --gen st" on a
recursive IDL died with SIGSEGV - on test/Recursive.thrift, on the
minimal self-recursive struct in the issue, and on mutually recursive
types.
Each generated struct class now carries its own serialization:
"writeTo: oprot" on the instance side and "readFrom: iprot" on the class
side. A struct-typed field compiles to a call to those rather than to a
copy of their bodies, so the generator visits each struct once and the
recursion is gone.
The bodies are the same code as before: struct_writer and struct_reader
are unchanged except that they are emitted once per struct instead of at
every use. The args and result structs a service synthesises are still
inlined into the send and recv methods, because they have no class to
hang a method on - and they no longer expand without bound, because the
expansion now stops at the first declared struct.
This also makes the depth limit from THRIFT-6052 mean something. Inlined,
the incrementRecursionDepth pairs counted lexical nesting, which is fixed
when the code is generated; now each struct counts one level per actual
call, so the limit applies to how deep the data is. Verified in Pharo on
a self-recursive type: depth 64 accepted, depth 65 rejected with
"Maximum recursion depth exceeded". That could not be tested before,
because a recursive type could not be generated at all.
Two things the restructure forced:
write_val emitted "iprot write..." for base types and enums while every
other part of the write path emitted "oprot". It worked only because
TClient>>inProtocol: defaults oprot to the same object, and would write
field values to the wrong protocol for anyone calling outProtocol:.
Inside "writeTo: oprot" there is no iprot at all, so these now say oprot.
read_val's struct case returns a keyword message rather than a block, so
it is parenthesised: "coll add: Foo readFrom: iprot" would otherwise
parse as a single add:readFrom: send.
Verification, all in Pharo against the generated code:
- a self-recursive type generates, files in, and round-trips a
five-deep value unchanged;
- the existing suites still pass on code from the new generator
(recursion depth 6 of 6, string size limit 11 of 11);
- for a non-recursive nested struct the bytes on the wire are
identical to those the old generator produced.
The regression guard is a compiler test, st_recursive_types, which runs
thrift --gen st over test/Recursive.thrift. It carries no
PASS_REGULAR_EXPRESSION on purpose: it passes only on a zero exit, and a
signal is not one. It fails with SEGFAULT before this change.
Generated Smalltalk changes shape for everyone: struct classes gain two
methods and service methods get shorter.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Client: swift
Remove the Swift compiler generator, library, tests, tutorial, and all
associated build system, CI, and documentation references. No maintainer
has been available for this binding; the lib-swift CI job has been
disabled since 0.23.0.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Client: compiler
Two improvements to the Markdown code generator:
1. Output files now use the .md extension by default (previously no
extension was appended). The existing 'suffix' option now also
accepts an empty value (suffix=) to explicitly suppress the extension.
This is a visible behaviour change for callers relying on the old
no-extension default.
2. @param and @return tags in function doc-comments are rendered as a
Markdown table instead of inline prose. Tags are only recognised at
the start of a line (after optional whitespace), so @-signs embedded
in ordinary text (email addresses, etc.) are left untouched.
Multi-line tag descriptions (continuation lines before the next tag)
are joined into a single table cell. '|' characters in cell content
are escaped as '\|' to protect table structure.
Adds a test fixture (DocTest.thrift), a golden reference file
(DocTest.md), a Python unittest script (markdown_doc_test.py), and a
corresponding CMake test target (MarkdownDocTest).
Applied clang-format to the entire file (pre-existing style issues
corrected alongside the new code).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Client: Compiler (general)
Patch: Jens Geyer
This also fixes an unhandled "normalize" case with enums in netstd that came up during tests for this ticket.
This closes#2715
Patch: Qinghui Xu
This closes#1898
In some environment, the file system only has second accuracy on
file modification timestamp, so delay of 0.1 second before
recompiling could makes the modification timestamp unchanged.
Deploy headers needed to build plugins
Restructure source tree to match lib and to make sure headers are
deployed to INCLUDE_DIR/thrift.
This closes#368 and closes#1039
Client: Compiler
Patch: Nobuaki Sukegawa, rebased by dtmuller
Also fixed by dtmuller:
* Add plugin namespace for erlang language binding
* Fix unit test test_const_value
* Don't clear type cache with every t_program conversion
* Type "wb" may not be supported by popen on non-Windows platforms
* Fix constness of AST type signatures