Skip to content

fix: correct #line directives in compiled templates#349

Draft
Koan-Bot wants to merge 1 commit into
cpan-authors:mainfrom
Koan-Bot:koan.atoomic/fix-compiled-line-numbers
Draft

fix: correct #line directives in compiled templates#349
Koan-Bot wants to merge 1 commit into
cpan-authors:mainfrom
Koan-Bot:koan.atoomic/fix-compiled-line-numbers

Conversation

@Koan-Bot

@Koan-Bot Koan-Bot commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

What

Compiled templates now emit correct #line directives for compound directives (IF, FOREACH, WHILE, SWITCH, TRY, WRAPPER, FILTER, VIEW, PERL).

Why

Fixes GH #306. When Template Toolkit compiles templates to Perl code, compound directives reported the END tag's line number instead of the opening keyword's line. For example, [% IF x == y %] on line 3 with [% END %] on line 5 would generate #line 5 instead of #line 3. This made error messages and debugging point to the wrong line.

How

The YACC grammar's chunk rule called location() after the entire compound directive (including its block body and END tag) was fully reduced — by which point the parser's line counter had advanced to the END line.

The fix adds a mid-rule grammar action after each compound directive's opening semicolon (before the block body is parsed) that captures location() while the line counter still points to the opening keyword. This captured #line string is prepended to the directive's compiled output. The chunk rule now checks if the statement already carries a #line prefix and skips its own location() call in that case.

Testing

  • Added t/compile-line-numbers.t with 8 tests covering IF, FOREACH, WHILE, and nested IF
  • Full test suite: 2885 tests passing (2877 existing + 8 new)

Closes #306

🤖 Generated with Claude Code


Quality Report

Changes: 3 files changed, 4469 insertions(+), 4256 deletions(-)

Code scan: 1 issue(s) found

  • lib/Template/Grammar.pm:0 — 4316 lines added

Tests: passed (OK)

Branch hygiene: clean

Generated by Kōan post-mission quality pipeline

)

Compound directives (IF, FOREACH, WHILE, SWITCH, TRY, WRAPPER,
FILTER, VIEW, PERL) reported the END tag's line number instead
of the opening keyword's line in compiled template cache files.

The fix captures location() in a mid-rule grammar action (after
the opening keyword's semicolon, before the block body) and
prepends it to the directive's compiled output. The chunk rule
skips its own location() call when the statement already carries
a #line directive, avoiding duplicates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@toddr

toddr commented May 24, 2026

Copy link
Copy Markdown
Member

@Koan-Bot rebase

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.

Compiled templates have incorrect line numbers for IF statements

2 participants