Pin verbatim export of snippet and Blueprint source - #285
Open
sirreal wants to merge 14 commits into
Open
Conversation
`Hook_Reflector::getName()` short-circuited on `Scalar\String_` nodes and returned the interpreted string value. Escape sequences were therefore resolved, so `do_action( "\x09tab" )` exported a literal tab and `do_action( "\xC0 bad" )` exported a raw 0xC0 byte. That byte is not valid UTF-8, `json_encode()` returns `false` for it, and `wp parser export` silently produced no JSON at all for the whole run. Route string nodes through `Pretty_Printer` like every other expression. The printer returns php-parser's `rawValue` attribute, which is the source-verbatim spelling, and `cleanupName()` strips the quotes. Also check `json_encode()` for failure in `Command::_get_phpdoc_data()` and fail loudly with `json_last_error_msg()` instead of writing an empty file.
The pretty printer inherits an override that returns PHP-Parser's `rawValue` attribute so escape sequences are not interpreted. PHP-Parser sets that attribute to the body of a doc string, without the delimiters, so `apply_filters( 'f', <<<EOT ... EOT, 2 )` exported its argument as a bare `body` string with embedded newlines instead of PHP source. Print heredoc and nowdoc nodes with the default printer, which reproduces the `<<<LABEL ... LABEL` form and does not interpret escape sequences in doc strings either.
`pName_FullyQualified()` prints single-segment fully-qualified names without the leading backslash regardless of namespace context, so inside a namespaced file the printed form denotes a namespaced symbol rather than the global one. This is an accepted limitation because the parser targets global-namespace WordPress core code.
The global namespace prefixes are stripped from inline `{@link}` and
`{@see}` references after the DocBlock text has been rendered, so the
stripping also reached into rendered code regions and silently deleted
the backslash an author had written in a verbatim code sample.
Carve out `<code>` regions before stripping, the same way `fix_newlines()`
protects the newlines in those regions, so code samples are exported as
they were written.
The quote-stripping pattern required a body free of quote characters, so a hook name that contained one, like `do_action( "it's" );`, was exported with the quotes that surround it in the source. Match the opening quote and require the same quote at the end, allowing the body to hold the other quote character or an escaped copy of the delimiter. Only that pair is stripped; the body keeps its source spelling, so `do_action( 'it\'s' );` exports as `it\'s`. Concatenated expressions still fall through to the dynamic-name handling below.
`Method_Call_Reflector::_getClassMapping()` maps a handful of WordPress factory functions to the class they return, so that `get_current_screen()->add_help_tab()` is exported as a use of `WP_Screen::add_help_tab()`. The lookup never matched before this branch, because the printed receiver carried a leading backslash that the mapping keys do not have. Pin the restored behavior with a test.
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.
Settles a policy question left open during the #262 rebase: after the targeted redesign of global-name prefix stripping,
doc.code_snippets[].code/expected_outputandsetup_blueprintsreceive no stripping at all — master's blanketarray_walk_recursiveused to touch them. That is the correct behavior — snippets and Blueprint definitions are executable, verbatim source, not prose — but nobody had stated it or pinned it.This adds a fixture whose snippet code, expected output, and Blueprint
writeFiledata all contain\-qualified global names, and asserts they export exactly as authored.The test passes on
fix-254. The same test run against master fails: the blanket walk rewrites the snippet toecho Docs_Global::greet();and the expected output toHello from Docs_Global— demonstrating that the pin captures a real difference in #262's behavior, not a tautology. (Master happens to leave this particular Blueprint data alone because its backslashes follow a newline and a quote rather than a space — which only underlines how incidental the old stripping was.)Targets
fix-254to land with #262.🤖 Generated with Claude Code