public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Set) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Twig_Node_Set, but got "%s".', get_class($node))); } $compiler->addDebugInfo($node); if (count($node->getNode('names')) > 1) { $values = $node->getNode('values'); foreach ($node->getNode('names') as $idx => $subNode) { $compiler->subcompile($subNode)->raw(' = ')->subcompile($values->getNode($idx))->raw(";\n"); } return; } $count = $this->count++; $captureStringBuffer = 'cSb' . ($count > 0 ? $count : ''); if ($node->getAttribute('capture')) { $compiler->write("var {$captureStringBuffer} = sb;\n")->write("sb = new twig.StringBuffer;")->subcompile($node->getNode('values')); } $compiler->subcompile($node->getNode('names'), false); if ($node->getAttribute('capture')) { $compiler->raw(" = new twig.Markup(sb.toString());\n")->write("sb = {$captureStringBuffer}"); } else { $compiler->raw(' = '); if ($node->getAttribute('safe')) { $compiler->raw("new twig.Markup(")->subcompile($node->getNode('values'))->raw(")"); } else { $compiler->subcompile($node->getNode('values')); } } $compiler->raw(";\n"); $this->count = $count; }
/** * {@inheritdoc} */ public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Expression_Name) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Expression_Name, but got "%s".', get_class($node))); } $name = $node->getAttribute('name'); if ($node->getAttribute('is_defined_test')) { if ($node->isSpecial()) { $compiler->repr(true); } else { $compiler->raw('(')->repr($name)->raw(' in context)'); } } elseif ($node->isSpecial()) { static $specialVars = ['_self' => 'this', '_context' => 'context', '_charset' => 'this.env_.getCharset()']; if (!isset($specialVars[$name])) { throw new \RuntimeException(sprintf('The special var "%s" is not supported by the NameCompiler.', $name)); } $compiler->raw($specialVars[$name]); } else { if (isset($compiler->localVarMap[$name])) { $compiler->raw($compiler->localVarMap[$name]); return; } // FIXME: Add strict behavior? // see Template::getContext() $compiler->raw('(')->string($name)->raw(' in context ? context[')->string($name)->raw('] : null')->raw(')'); } }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Expression_MacroCall) { throw new \LogicException(sprintf('This compiler does not support the type "%s".', get_class($node))); } $argsNode = $node->getNode('arguments'); if (!$argsNode instanceof \Twig_Node_Expression_Array) { throw new \LogicException('Did not find args node.'); } $namedNames = array(); $namedCount = 0; $positionalCount = 0; foreach ($argsNode->getKeyValuePairs() as $pair) { $name = $pair['key']->getAttribute('value'); if (!is_int($name)) { $namedCount++; $namedNames[$name] = 1; } elseif ($namedCount > 0) { throw new \Twig_Error_Syntax(sprintf('Positional arguments cannot be used after named arguments for macro "%s".', $node->getAttribute('name')), $node->getLine()); } else { $positionalCount++; } } $compiler->raw('this.callMacro(')->subcompile($node->getNode('template'))->raw(', ')->repr($node->getAttribute('name'))->raw(', ')->subcompile($argsNode); if ($namedCount > 0) { $compiler->raw(', ')->repr($namedNames)->raw(', ')->repr($namedCount)->raw(', ')->repr($positionalCount); } $compiler->raw(')'); }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Expression_ExtensionReference) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Twig_Node_Expression_ExtensionReference, but got "%s".', get_class($node))); } $compiler->raw("this.env_.getExtension(")->subcompile($node->getNode('name'))->raw(")"); if ($output) { $compiler->raw(";\n"); } }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Expression_Parent) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Twig_Node_Expression_Parent, but got "%s".', get_class($node))); } if ($output = $node->getAttribute('output')) { $compiler->addDebugInfo($node)->write("sb.append("); } $compiler->raw("this.renderParentBlock(")->string($node->getAttribute('name'))->raw(", context, blocks)"); if ($output) { $compiler->raw(");\n"); } }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Import) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Twig_Node_Import, but got "%s".', get_class($node))); } $compiler->addDebugInfo($node)->write("")->subcompile($node->getNode('var'))->raw(' = '); if ($node->getNode('expr') instanceof Twig_Node_Expression_Name && '_self' === $node->getNode('expr')->getAttribute('name')) { $compiler->raw("this"); } else { $compiler->raw('this.env_.createTemplate(')->setTemplateName(true)->subcompile($node->getNode('expr'))->setTemplateName(false)->raw(")"); } $compiler->raw(";\n"); }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Expression_GetAttr) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Expression_GetAttr, but got "%s".', get_class($node))); } $compiler->raw('twig.attr('); if ($node->getAttribute('is_defined_test') && $compiler->getEnvironment()->isStrictVariables()) { $compiler->subcompile(new \Twig_Node_Expression_Filter($node->getNode('node'), new \Twig_Node_Expression_Constant('default', $node->getLine()), new \Twig_Node(), $node->getLine())); } else { $compiler->subcompile($node->getNode('node')); } $compiler->raw(', ')->subcompile($node->getNode('attribute')); $defaultArguments = 0 === count($node->getNode('arguments')); $defaultAccess = \Twig_TemplateInterface::ANY_CALL === $node->getAttribute('type'); $defaultTest = false == $node->getAttribute('is_defined_test'); if (!$defaultArguments) { $compiler->raw(', ')->subcompile($node->getNode('arguments')); } elseif (!$defaultAccess || !$defaultTest) { $compiler->raw(', undefined'); } if (!$defaultAccess) { $compiler->raw(', ')->repr($node->getAttribute('type')); } elseif (!$defaultTest) { $compiler->raw(', undefined'); } if (!$defaultTest) { $compiler->raw(', ' . ($node->getAttribute('is_defined_test') ? 'true' : 'false')); } $compiler->raw(')'); }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Expression_MethodCall) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Twig_Node_Expression_MethodCall, but got "%s".', get_class($node))); } $compiler->subcompile($node->getNode('node'))->raw('.')->raw($node->getAttribute('method'))->raw('('); $first = true; foreach ($node->getNode('arguments')->getKeyValuePairs() as $pair) { if (!$first) { $compiler->raw(', '); } $first = false; $compiler->subcompile($pair['value']); } $compiler->raw(')'); }
protected function operator(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Expression_Binary_NotEqual) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Twig_Node_Expression_Binary_NotEqual, but got "%s".', get_class($node))); } return $compiler->raw('!='); }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Expression_Binary_Power) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Twig_Node_Expression_Binary_Power, but got "%s".', get_class($node))); } $compiler->raw('Math.pow(')->subcompile($this->getNode('left'))->raw(', ')->subcompile($this->getNode('right'))->raw(')'); }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Expression_AssignName) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Expression_AssignName, but got "%s".', get_class($node))); } $compiler->raw('context[')->string($node->getAttribute('name'))->unsetVar($node->getAttribute('name'))->raw(']'); }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Expression_Conditional) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Expression_Conditional, but got "%s".', get_class($node))); } $compiler->raw('((')->subcompile($node->getNode('expr1'))->raw(') ? (')->subcompile($node->getNode('expr2'))->raw(') : (')->subcompile($node->getNode('expr3'))->raw('))'); }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Expression_Binary_NotIn) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Twig_Node_Expression_Binary_NotIn, but got "%s".', get_class($node))); } // order of arguments is reversed, see the InCompiler $compiler->raw('!twig.contains(')->subcompile($node->getNode('right'))->raw(', ')->subcompile($node->getNode('left'))->raw(')'); }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Expression_Function) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Expression_Function, but got "%s".', get_class($node))); } $function = $compiler->getEnvironment()->getFunction($node->getAttribute('name')); if (false === $function) { throw new \Twig_Error_Syntax(sprintf('The function "%s" does not exist', $node->getAttribute('name')), $node->getLine()); } if ($jsFunction = $compiler->getJsFunction($node->getAttribute('name'))) { $compiler->raw($jsFunction . '('); } else { $compiler->raw('this.env_.invoke(')->string($node->getAttribute('name'))->raw(', '); } $compiler->raw($function->needsEnvironment() ? 'this.env_' : ''); if ($function->needsContext()) { $compiler->raw($function->needsEnvironment() ? ', context' : 'context'); } $first = true; foreach ($node->getNode('arguments') as $argNode) { if (!$first) { $compiler->raw(', '); } else { if ($function->needsEnvironment() || $function->needsContext()) { $compiler->raw(', '); } $first = false; } $compiler->subcompile($argNode); } $compiler->raw(')'); }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Expression_Array) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Expression_Array, but got "%s".', get_class($node))); } $pairs = $this->getKeyValuePairs($node); if ($isList = $this->isList($pairs)) { $compiler->raw('['); } elseif ($hasDynamicKeys = $this->hasDynamicKeys($pairs)) { $compiler->raw('twig.createObj('); } else { $compiler->raw('{'); } $first = true; foreach ($pairs as $pair) { if (!$first) { $compiler->raw(', '); } $first = false; if ($isList) { $compiler->subcompile($pair['value']); } elseif ($hasDynamicKeys) { $compiler->subcompile($pair['key'])->raw(', ')->subcompile($pair['value']); } else { $compiler->subcompile($pair['key'])->raw(': ')->subcompile($pair['value']); } } if ($isList) { $compiler->raw(']'); } elseif ($hasDynamicKeys) { $compiler->raw(')'); } else { $compiler->raw('}'); } }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Include) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Include, but got "%s".', get_class($node))); } $compiler->addDebugInfo($node); // Is there are use case for conditional includes at runtime? // if ($node->getAttribute('ignore_missing')) { // $compiler // ->write("try {\n") // ->indent() // ; // } $compiler->isTemplateName = true; if ($node->getNode('expr') instanceof Twig_Node_Expression_Constant) { $compiler->write("(new ")->subcompile($node->getNode('expr'))->raw("(this.env_)).render_(sb, "); } else { $compiler->write("(new ")->subcompile($node->getNode('expr'))->raw("(this.env_)).render_(sb, "); } $compiler->isTemplateName = false; if (false === $node->getAttribute('only')) { if (null === $node->getNode('variables')) { $compiler->raw('context'); } else { $compiler->raw('twig.extend({}, context, ')->subcompile($node->getNode('variables'))->raw(')'); } } else { if (null === $node->getNode('variables')) { $compiler->raw('{}'); } else { $compiler->subcompile($node->getNode('variables')); } } $compiler->raw(");\n"); // if ($node->getAttribute('ignore_missing')) { // $compiler // ->outdent() // ->write("} catch (Twig_Error_Loader \$e) {\n") // ->indent() // ->write("// ignore missing template\n") // ->outdent() // ->write("}\n\n") // ; // } }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Expression_Unary) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Expression_Unary, but got "%s".', get_class($node))); } $compiler->raw('('); $this->operator($compiler, $node); $compiler->subcompile($node->getNode('node'))->raw(')'); }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Expression_TempName) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Twig_Node_Expression_TempName, but got "%s".', get_class($node))); } $name = $node->getAttribute('name'); if (isset($compiler->localVarMap[$name])) { $compiler->raw($compiler->localVarMap[$name]); return; } /* Contrary to the name of this class, this code no longer compiles the name of the node to a temporary variable name. Because of the troubles resulting from this optimization reported in schmittjoh/twig.js#12, this has been replaced with the slightly less performant but more reliable NameCompiler output which reads the variable directly from the context. */ $compiler->raw('(')->string($name)->raw(' in context ? context[')->string($name)->raw('] : null)'); }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Expression_Binary_In) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Twig_Node_Expression_Binary_In, but got "%s".', get_class($node))); } // order left,right is reversed in JsCompiler compared to Twig_Compiler // since the twig.contains filter takes reverse arguments to follow // Google Closure conventions $compiler->raw('twig.contains(')->subcompile($node->getNode('right'))->raw(', ')->subcompile($node->getNode('left'))->raw(')'); }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Expression_Constant) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Expression_Constant, but got "%s".', get_class($node))); } if ($compiler->isTemplateName) { $env = $compiler->getEnvironment(); $source = $env->getLoader()->getSource($node->getAttribute('value')); $module = $env->parse($env->tokenize($source, $node->getAttribute('value'))); $compiler->raw($compiler->getFunctionName($module)); return; } $compiler->repr($node->getAttribute('value')); }
protected function compileConstructor(JsCompiler $compiler, \Twig_NodeInterface $node) { $compiler->raw("\n"); $countTraits = count($node->getNode('traits')); if ($countTraits) { // traits foreach ($node->getNode('traits') as $i => $trait) { $this->compileLoadTemplate($compiler, $trait->getNode('template'), sprintf('trait_%s', $i)); $compiler->addDebugInfo($trait->getNode('template'))->write(sprintf("if (!trait_%s.isTraitable()) {\n", $i))->indent()->write("throw Error('Template \"' + trait_" . $i . ".getTemplateName() + " . "'\" cannot be used as a trait.');\n")->outdent()->write("}\n")->write(sprintf("var trait_%s_blocks = trait_%s.getBlocks();\n\n", $i, $i)); foreach ($trait->getNode('targets') as $key => $value) { $compiler->write(sprintf("trait_%s_blocks[", $i))->subcompile($value)->raw(sprintf("] = trait_%s_blocks[", $i))->string($key)->raw(sprintf("]; delete trait_%s_blocks[", $i))->string($key)->raw("];\n\n"); } } $compiler->write("var traits = twig.extend({},\n")->indent(); for ($i = 0; $i < $countTraits; $i++) { $compiler->write(sprintf("trait_%s_blocks" . ($i == $countTraits - 1 ? '' : ',') . "\n", $i)); } $compiler->outdent()->write(");\n")->write("this.setTraits(traits);\n\n"); $compiler->write("this.setBlocks(twig.extend({}, traits, {\n"); } else { $compiler->write("this.setBlocks({\n"); } // blocks $compiler->indent(); $first = true; foreach ($node->getNode('blocks') as $name => $node) { if (!$first) { $compiler->raw(",\n"); } $first = false; $compiler->write(sprintf("'%s': twig.bind(this.block_%s, this)", $name, $name)); } if (!$first) { $compiler->raw("\n"); } if ($countTraits) { $compiler->outdent()->write("}));\n"); } else { $compiler->outdent()->write("});\n"); } }
public function compile(JsCompiler $compiler, \Twig_Node_Expression_Filter $node) { if (!($locale = $compiler->getDefine('locale')) || !$this->translator instanceof Translator) { return false; } // unfortunately, the Translation component does not provide a better // way to retrieve these $this->loadCatalogueRef = new \ReflectionMethod($this->translator, 'loadCatalogue'); $this->loadCatalogueRef->setAccessible(true); $this->catalogueRef = new \ReflectionProperty($this->translator, 'catalogues'); $this->catalogueRef->setAccessible(true); // ignore dynamic messages, we cannot resolve these // users can still apply a runtime trans filter to do this $subNode = $node->getNode('node'); if (!$subNode instanceof \Twig_Node_Expression_Constant) { return false; } $id = $subNode->getAttribute('value'); $domain = 'messages'; $hasParams = false; $arguments = $node->getNode('arguments'); if (count($arguments) > 0) { $hasParams = count($arguments->getNode(0)) > 0; if ($arguments->hasNode(1)) { $domainNode = $arguments->getNode(1); if (!$domainNode instanceof \Twig_Node_Expression_Constant) { return false; } $domain = $domainNode->getAttribute('value'); } } $catalogue = $this->getCatalogue($locale); if (!$hasParams) { $compiler->string($catalogue->get($id, $domain)); return; } $compiler->raw('twig.filter.replace(')->string($catalogue->get($id, $domain))->raw(", ")->subcompile($arguments->getNode(0))->raw(')'); }
protected function operator(JsCompiler $compiler, \Twig_NodeInterface $node) { return $compiler->raw('/'); }
public function compile(JsCompiler $compiler, \Twig_Node_Expression_Test $node) { $compiler->raw('(')->subcompile($node->getNode('node'))->raw(' === ')->subcompile($node->getNode('arguments')->getNode(0))->raw(')'); }
public function compile(JsCompiler $compiler, \Twig_Node_Expression_Test $node) { $compiler->raw('1 === ')->subcompile($node->getNode('node'))->raw(' % 2'); }