Example #1
0
 /**
  * @param Node $node
  * @param string $name
  * @param string $parent
  * @param string[] $includes
  * @param string[] $filters
  */
 function __construct(Node $node, $name = NULL, $parent = NULL, array $includes = NULL, array $filters = NULL)
 {
     $this->m_name = $name != NULL ? $name : $node->name();
     $this->m_root = $node;
     if ($includes) {
         $this->m_parent = $parent;
         $this->m_includes = $includes;
         $this->m_filters = $filters;
     } else {
         // check first child for inheritance
         if (($firstChild = $node->firstToken()) && $firstChild->type() === TokenType::T_INHERIT) {
             $this->m_parent = $firstChild->name();
         }
         // include dependency names
         $this->m_includes = array_map('strval', iterator_to_array($node->GetChildrenByType(TokenType::T_INCLUDE, true)));
         /** @var EvalNameToken $token */
         $this->m_filters = [];
         foreach ($node->GetChildrenByClass(EvalNameToken::class, true) as $token) {
             foreach ($token->filters() as $filter) {
                 $this->m_filters[$filter] = $filter;
             }
         }
     }
 }
Example #2
0
 /**
  * @param Node $node
  * @param array $definitions
  */
 public function replaceContents($node, array $definitions = NULL)
 {
     // remove existing children
     foreach ($this->m_children as $child) {
         if ($child instanceof self) {
             $child->m_parent = NULL;
         }
     }
     $this->m_children = [];
     // add children from other node
     foreach ($node->m_children as $child) {
         if ($child instanceof IToken) {
             if ($child instanceof self) {
                 $newChild = new self($child->m_token, $this);
                 $newChild->replaceContents($child, $definitions);
                 $child = $newChild;
             } else {
                 if ($definitions != NULL && $child->type() === TokenType::T_VARIABLE && isset($definitions[$child->name()])) {
                     // replace this token/node with a new node
                     $def = $definitions[$child->name()];
                     $token = $child instanceof self ? $child->m_token : $child;
                     $child = new Node($token, $this);
                     $child->replaceContents($def);
                 }
             }
         }
         $this->m_children[] = $child;
     }
 }
Example #3
0
 private static function parse(Generator $files)
 {
     $templates = [];
     /** @var Node[] $stack */
     $stack = [];
     /** @var Node $node */
     $node = NULL;
     foreach ($files as $tokens) {
         foreach ($tokens as $token) {
             if (is_string($token)) {
                 if ($node !== NULL) {
                     $node->addChild($token);
                 }
                 /*else {
                 			if (!$token instanceof TextToken) {
                 				// something other than whitespace/template at the root level
                 			}
                 		}*/
             } else {
                 if (is_int($token)) {
                     if ($token === TokenType::T_CLOSE) {
                         $type = $node->type();
                         if ($type === TokenType::T_TEMPLATE || $type === TokenType::T_SOURCE) {
                             // add to template list
                             $name = $node->name();
                             if ($type === TokenType::T_SOURCE) {
                                 // generate name for "anonymous" template (there will be something on the stack for this type)
                                 $parent = end($stack);
                                 while ($parent->parent()) {
                                     $parent = $parent->parent();
                                 }
                                 $templateParentPrefix = $parent->name();
                                 $name = TokenType::T_ANONYMOUS_TEMPLATE_PREFIX . $templateParentPrefix . TokenType::T_ANONYMOUS_TEMPLATE_DELIMITER . $name;
                             }
                             if (isset($templates[$name])) {
                                 throw new \Exception("Duplicate template definition: `{$name}`");
                             }
                             $templates[$name] = new Template($node, $name);
                             // templates don't have a parent, so check the nesting stack
                             if ($parent = array_pop($stack)) {
                                 // this is a nested template (replace with include token)
                                 $includeToken = new NameToken(TokenType::T_INCLUDE, $name);
                                 $parent->AddChild($includeToken);
                             }
                             $node = $parent;
                         } else {
                             $node = $node->parent();
                         }
                     }
                 } else {
                     if ($token instanceof IToken) {
                         $type = $token->type();
                         if ($type === TokenType::T_TEMPLATE || $type === TokenType::T_SOURCE) {
                             if ($node != NULL) {
                                 // save current node if this is a nested definition
                                 $stack[] = $node;
                             } else {
                                 if ($type != TokenType::T_TEMPLATE) {
                                     throw new \Exception('Only explicit templates allowed at root level');
                                 }
                             }
                             // start new template node (with no parent)
                             $node = new Node($token);
                         } else {
                             if (!TokenType::void($type)) {
                                 if ($node != NULL) {
                                     // this is not a self-closing tag, so start a new node now
                                     $child = new Node($token, $node);
                                     $node->addChild($child);
                                     $node = $child;
                                 }
                             } else {
                                 if ($node != NULL) {
                                     $node->addChild($token);
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     return $templates;
 }