diff --git a/lib/Twig/Node/Module.php b/lib/Twig/Node/Module.php index 9f66b28d5..745d2d7e7 100644 --- a/lib/Twig/Node/Module.php +++ b/lib/Twig/Node/Module.php @@ -77,17 +77,18 @@ class Twig_Node_Module extends Twig_Node protected function compileGetParent(Twig_Compiler $compiler) { - if (null === $this->getNode('parent')) { + if (null === $parent = $this->getNode('parent')) { return; } $compiler ->write("protected function doGetParent(array \$context)\n", "{\n") ->indent() + ->addDebugInfo($parent) ->write("return ") ; - if ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) { + if ($parent instanceof Twig_Node_Expression_Constant) { $compiler->subcompile($this->getNode('parent')); } else { $compiler @@ -108,8 +109,9 @@ class Twig_Node_Module extends Twig_Node { $compiler->subcompile($this->getNode('body')); - if (null !== $this->getNode('parent')) { - if ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) { + if (null !== $parent = $this->getNode('parent')) { + $compiler->addDebugInfo($parent); + if ($parent instanceof Twig_Node_Expression_Constant) { $compiler->write("\$this->parent"); } else { $compiler->write("\$this->getParent(\$context)"); @@ -140,13 +142,24 @@ class Twig_Node_Module extends Twig_Node ; // parent - if (null === $this->getNode('parent')) { + if (null === $parent = $this->getNode('parent')) { $compiler->write("\$this->parent = false;\n\n"); - } elseif ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) { + } elseif ($parent instanceof Twig_Node_Expression_Constant) { $compiler + ->addDebugInfo($parent) + ->write("try {\n") + ->indent() ->write("\$this->parent = \$this->env->loadTemplate(") ->subcompile($this->getNode('parent')) - ->raw(");\n\n") + ->raw(");\n") + ->outdent() + ->write("} catch (Twig_Error_Loader \$e) {\n") + ->indent() + ->write("\$e->setTemplateFile(\$this->getTemplateName());\n") + ->write(sprintf("\$e->setTemplateLine(%d);\n\n", $parent->getLine())) + ->write("throw \$e;\n") + ->outdent() + ->write("}\n\n") ; } @@ -249,7 +262,7 @@ class Twig_Node_Module extends Twig_Node ->outdent() ->write(");\n") ->outdent() - ->write("}\n\n"); + ->write("}\n\n") ; } diff --git a/lib/Twig/Template.php b/lib/Twig/Template.php index 63910dacc..37a7a820a 100644 --- a/lib/Twig/Template.php +++ b/lib/Twig/Template.php @@ -20,7 +20,6 @@ abstract class Twig_Template implements Twig_TemplateInterface protected static $cache = array(); protected $parent; - protected $parents; protected $env; protected $blocks; protected $traits; @@ -62,22 +61,19 @@ abstract class Twig_Template implements Twig_TemplateInterface */ public function getParent(array $context) { - if (null !== $this->parent) { - return $this->parent; + if (null === $this->parent) { + try { + $parent = $this->doGetParent($context); + $this->parent = false === $parent ? false : $this->env->resolveTemplate($parent); + } catch (Twig_Error_Loader $e) { + $e->setTemplateFile(null); + $e->guess(); + + throw $e; + } } - $parent = $this->doGetParent($context); - if (false === $parent) { - return false; - } elseif ($parent instanceof Twig_Template) { - $name = $parent->getTemplateName(); - $this->parents[$name] = $parent; - $parent = $name; - } elseif (!isset($this->parents[$parent])) { - $this->parents[$parent] = $this->env->loadTemplate($parent); - } - - return $this->parents[$parent]; + return $this->parent; } protected function doGetParent(array $context) diff --git a/test/Twig/Tests/Fixtures/exceptions/undefined_parent.test b/test/Twig/Tests/Fixtures/exceptions/undefined_parent.test new file mode 100644 index 000000000..c8e7a0973 --- /dev/null +++ b/test/Twig/Tests/Fixtures/exceptions/undefined_parent.test @@ -0,0 +1,8 @@ +--TEST-- +Exception for an undefined parent +--TEMPLATE-- +{% extends 'foo.html' %} + +{% set foo = "foo" %} +--EXCEPTION-- +Twig_Error_Loader: Template "foo.html" is not defined in "index.twig" at line 2. diff --git a/test/Twig/Tests/Node/ModuleTest.php b/test/Twig/Tests/Node/ModuleTest.php index b8996edf4..6c012b8c9 100644 --- a/test/Twig/Tests/Node/ModuleTest.php +++ b/test/Twig/Tests/Node/ModuleTest.php @@ -96,7 +96,7 @@ class __TwigTemplate_a2bfbf7dd6ab85666684fe9297f69363a3fc2046d90f22a317d380c1863 EOF , $twig); - $import = new Twig_Node_Import(new Twig_Node_Expression_Constant('foo.twig', 1), new Twig_Node_Expression_AssignName('macro', 1), 1); + $import = new Twig_Node_Import(new Twig_Node_Expression_Constant('foo.twig', 1), new Twig_Node_Expression_AssignName('macro', 1), 2); $body = new Twig_Node(array($import)); $extends = new Twig_Node_Expression_Constant('layout.twig', 1); @@ -112,7 +112,15 @@ class __TwigTemplate_a2bfbf7dd6ab85666684fe9297f69363a3fc2046d90f22a317d380c1863 { parent::__construct(\$env); - \$this->parent = \$this->env->loadTemplate("layout.twig"); + // line 1 + try { + \$this->parent = \$this->env->loadTemplate("layout.twig"); + } catch (Twig_Error_Loader \$e) { + \$e->setTemplateFile(\$this->getTemplateName()); + \$e->setTemplateLine(1); + + throw \$e; + } \$this->blocks = array( ); @@ -125,8 +133,9 @@ class __TwigTemplate_a2bfbf7dd6ab85666684fe9297f69363a3fc2046d90f22a317d380c1863 protected function doDisplay(array \$context, array \$blocks = array()) { - // line 1 + // line 2 \$context["macro"] = \$this->env->loadTemplate("foo.twig"); + // line 1 \$this->parent->display(\$context, array_merge(\$this->blocks, \$blocks)); } @@ -142,18 +151,19 @@ class __TwigTemplate_a2bfbf7dd6ab85666684fe9297f69363a3fc2046d90f22a317d380c1863 public function getDebugInfo() { - return array ( 24 => 1,); + return array ( 34 => 1, 32 => 2, 11 => 1,); } } EOF , $twig); - $body = new Twig_Node(); + $set = new Twig_Node_Set(false, new Twig_Node(array(new Twig_Node_Expression_AssignName('foo', 4))), new Twig_Node(array(new Twig_Node_Expression_Constant("foo", 4))), 4); + $body = new Twig_Node(array($set)); $extends = new Twig_Node_Expression_Conditional( - new Twig_Node_Expression_Constant(true, 1), - new Twig_Node_Expression_Constant('foo', 1), - new Twig_Node_Expression_Constant('foo', 1), - 0 + new Twig_Node_Expression_Constant(true, 2), + new Twig_Node_Expression_Constant('foo', 2), + new Twig_Node_Expression_Constant('foo', 2), + 2 ); $node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, new Twig_Node(array()), $filename); @@ -165,11 +175,15 @@ class __TwigTemplate_a2bfbf7dd6ab85666684fe9297f69363a3fc2046d90f22a317d380c1863 { protected function doGetParent(array \$context) { + // line 2 return \$this->env->resolveTemplate(((true) ? ("foo") : ("foo"))); } protected function doDisplay(array \$context, array \$blocks = array()) { + // line 4 + \$context["foo"] = "foo"; + // line 2 \$this->getParent(\$context)->display(\$context, array_merge(\$this->blocks, \$blocks)); } @@ -185,7 +199,7 @@ class __TwigTemplate_a2bfbf7dd6ab85666684fe9297f69363a3fc2046d90f22a317d380c1863 public function getDebugInfo() { - return array (); + return array ( 17 => 2, 15 => 4, 9 => 2,); } } EOF diff --git a/test/Twig/Tests/Node/SandboxedModuleTest.php b/test/Twig/Tests/Node/SandboxedModuleTest.php index bb9ffb782..b42f776bb 100644 --- a/test/Twig/Tests/Node/SandboxedModuleTest.php +++ b/test/Twig/Tests/Node/SandboxedModuleTest.php @@ -142,7 +142,15 @@ class __TwigTemplate_a2bfbf7dd6ab85666684fe9297f69363a3fc2046d90f22a317d380c1863 { parent::__construct(\$env); - \$this->parent = \$this->env->loadTemplate("layout.twig"); + // line 1 + try { + \$this->parent = \$this->env->loadTemplate("layout.twig"); + } catch (Twig_Error_Loader \$e) { + \$e->setTemplateFile(\$this->getTemplateName()); + \$e->setTemplateLine(1); + + throw \$e; + } \$this->blocks = array( ); @@ -198,7 +206,7 @@ class __TwigTemplate_a2bfbf7dd6ab85666684fe9297f69363a3fc2046d90f22a317d380c1863 public function getDebugInfo() { - return array (); + return array ( 11 => 1,); } } EOF