fix: detect Statement::Variable in open() without parens#370
Draft
toddr-bot wants to merge 2 commits into
Draft
Conversation
When open() is called without parentheses (e.g., `open my $fh, "<", $path`),
PPI does not wrap the `my $fh` portion in a PPI::Statement::Variable, even
though the parenthesized form `open(my $fh, "<", $path)` does. This makes
variable declarations invisible to `$doc->find('Statement::Variable')`.
Tests are marked $TODO and will pass once the lexer fix is applied.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…225) When a variable declaration keyword (my/local/our/state) appears inside a plain PPI::Statement that already has children (e.g. `open my $fh`), the lexer now creates a child PPI::Statement::Variable to wrap the declaration. This makes `$doc->find('Statement::Variable')` correctly detect variable declarations in builtin calls without parentheses, matching the behavior when parentheses are used. Three changes work together: - _lex_statement() detects my/local/our/state inside plain statements and creates a child Variable, confirmed by peeking ahead for a symbol or open paren - Statement::Variable overrides __LEXER__normal to return false when nested inside another statement, preventing it from consuming the semicolon - _continues() returns false for ';' on nested Variable statements, rolling the semicolon back to the parent Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.
Summary
When
open my $fh, "<", $path;is parsed without parentheses, PPI did not wrap themy $fhportion in aPPI::Statement::Variable, making the variable declaration invisible to$doc->find('Statement::Variable'). The parenthesized formopen(my $fh, ...)already worked correctly.This fix teaches the lexer to detect
my/local/our/statedeclarations inside plain statements and create a childPPI::Statement::Variablenode, consistent with the parenthesized behavior.Fixes #225
Changes
_lex_statement()now detects variable declaration keywords inside plainPPI::Statementnodes and creates a childPPI::Statement::Variablewhen confirmed by a peek-ahead (next significant token is a symbol or()PPI::Statement::Variableoverrides__LEXER__normalto return false when nested inside another statement, preventing it from consuming the parent's;_continues()handles nested Variable statements by ending at;(rolling it back to the parent)Test plan
open my $fhwithout parens: verifiesfind('Statement::Variable')returns the declaration with correcttype()andvariables()print my $x = 1;(another builtin without parens)func my => 1;(fat comma) does NOT create a VariableGenerated by Kōan /fix
Quality Report
Changes: 3 files changed, 108 insertions(+), 1 deletion(-)
Code scan: clean
Tests: skipped
Branch hygiene: clean
Generated by Kōan post-mission quality pipeline