Set of discovered variable names. */ public array $variables = []; public function enterNode(Node $node, Environment $env): Node { if ($node instanceof ContextVariable || $node instanceof TemplateVariable) { $name = $node->getAttribute('name'); if (is_string($name) && $name !== '' && !str_starts_with($name, '_')) { $this->variables[$name] = true; } } elseif ($node instanceof AssignNameExpression) { $name = $node->getAttribute('name'); if (is_string($name) && $name !== '' && !str_starts_with($name, '_')) { $this->variables[$name] = true; } } elseif ($node instanceof EmbedNode || $node instanceof IncludeNode) { // The `with { foo: bar }` block on embed/include passes its keys // as variables into the embedded template. Stub those too. $variables = $node->hasNode('variables') ? $node->getNode('variables') : null; if ($variables instanceof ArrayExpression) { foreach ($variables->getKeyValuePairs() as $pair) { $key = $pair['key']; if ($key instanceof ConstantExpression) { $k = $key->getAttribute('value'); if (is_string($k) && $k !== '' && !str_starts_with($k, '_')) { $this->variables[$k] = true; } } } } } return $node; } public function leaveNode(Node $node, Environment $env): ?Node { return $node; } public function getPriority(): int { return 0; } /** * @return list */ public function getVariableNames(): array { return array_keys($this->variables); } }