Compiles a filter-node into PHTML.

The filters are drawn from the filters-option

@param Node $node the filter node to compile

@return string The compiled PHTML
@throws Exception
488611
protected function compileFilter(Node $node)
    {

        $name = $node->name;

        if (!isset($this->options['filters'][$name]))
            $this->throwException(
                "Filter $name was not defined. Make sure to add it via the [`filters`]-option or the [`->addFilter`]-method ",
                $node
            );

        $result = call_user_func($this->options['filters'][$name], $node, $this->indent(), $this->newLine(), $this);

        return $result instanceof Node ? $this->compileNode($result) : (string)$result;
    }
210387
public function enterNode(Node $node)
    {
        parent::enterNode($node);

        if (self::isConditional($node)) {
            $this->conditionalScopes++;
        } elseif ($node instanceof Function_) {
            $name = $this->getFullyQualifiedName($node->name);

            // @todo add an "else" here which adds a runtime check for instances where we can't tell
            // whether a function is being redefined by static analysis alone.
            if ($this->conditionalScopes === 0) {
                if (\function_exists($name) ||
                    isset($this->currentScope[\strtolower($name)])) {
                    $msg = \sprintf('Cannot redeclare %s()', $name);
                    throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine());
                }
            }

            $this->currentScope[\strtolower($name)] = true;
        }
    }
1076523
function it_compiles_nodes($node)
    {
        $node->compile($this)->will(function ($args) {
            $args[0]->write('echo $message');
        });

        $this->compile($node)->getSource()->shouldMatch('/\Recho \$message/');
    }
1281445
public static function fromNode($node)
    {
        $p = new self();
        $p->setNid($node->id());
        $p->setPhpVersion('7.0');
        if ($node->hasField('field_pull_request_template') && !$node->get('field_pull_request_template')->isEmpty()) {
            $p->setCustomPrMessage($node->get('field_pull_request_template')->first()->getString());
        }
        if (!$p->getCustomPrMessage()) {
            // See if we have a default one on the user.
            $owner = $node->getOwner();
            if ($owner->hasField('field_user_pr_template') && !$owner->get('field_user_pr_template')->isEmpty()) {
                $p->setCustomPrMessage($owner->get('field_user_pr_template')->first()->getString());
            }
        }
        if ($node->hasField('field_php_version') && !$node->get('field_php_version')->isEmpty()) {
            $p->setPhpVersion($node->get('field_php_version')->first()->getString());
        }
        $owner = $node->getOwner();
        if ($owner) {
            $p->setRoles($owner->getRoles());
        }
        return $p;
    }
1271682
public function enterNode(PhpParser\Node $node)
    {
        $attrs = $node->getAttributes();

        if ($cs = $node->getComments()) {
            $new_comments = [];

            foreach ($cs as $c) {
                if ($c instanceof PhpParser\Comment\Doc) {
                    $new_comments[] = new PhpParser\Comment\Doc(
                        $c->getText(),
                        $c->getLine() + $this->line_offset,
                        $c->getFilePos() + $this->file_offset
                    );
                } else {
                    $new_comments[] = new PhpParser\Comment(
                        $c->getText(),
                        $c->getLine() + $this->line_offset,
                        $c->getFilePos() + $this->file_offset
                    );
                }
            }

            $node->setAttribute('comments', $new_comments);
        }

        /** @psalm-suppress MixedOperand */
        $node->setAttribute('startFilePos', $attrs['startFilePos'] + $this->file_offset);
        /** @psalm-suppress MixedOperand */
        $node->setAttribute('endFilePos', $attrs['endFilePos'] + $this->file_offset);
        /** @psalm-suppress MixedOperand */
        $node->setAttribute('startLine', $attrs['startLine'] + $this->line_offset);
    }
943425
private function validateTypeFieldIsPresent($node)
    {
        if (empty($node['_type'])) {
            throw new Exception("Element: {$this->currentNode} has no compulsory field: _type", ValidatorResult::ERROR_NODE_HAS_NO_FIELD_TYPE);
        }

        $this->getLogger()->info("Element: {$this->currentNode} has field: _type");
    }
341259
protected function getNodeString(Filter $node, Compiler $compiler = null)
    {
        return array_reduce($node->block->nodes, function(&$result, $line) use($compiler) {
            $val = $compiler ? $compiler->interpolate($line->value) : $line->value;
            return $result .= $val."\n";
        });
    }
997722
protected function renderNode($node)
    {
        if (is_string($node)) {
            $node = ['name' => $node];
        }
        if (!isset($node['name'])) {
            throw new InvalidConfigException("The 'name' option is required.");
        }

        $lines = [];

        $nodeOptions = array_merge([
            'data-node-id' => $node['id'],
            'data-node-name' => Html::encode($node['name']),
            'data-action-name' => 'move',   ///[node move action]
            'data-action-url' => Url::to(ArrayHelper::getValue($node, 'move-url', $this->createUrl('move', $node))),
            // more node data ...
        ], $this->nodeOptions, ArrayHelper::getValue($node, 'options', []));
        $tag = ArrayHelper::remove($nodeOptions, 'tag', 'li');

        $lines[] = Html::beginTag($tag, $nodeOptions);

        $lines[] = Html::beginTag('div');

        $lines[] = $this->renderNodeName($node);
        $lines[] = $this->renderNodeActions($node);

        $lines[] = Html::endTag('div');

        if (!empty($node['nodes'])) {
            $lines[] =  $this->renderNodes($node['nodes']);
        }

        $lines[] =  Html::endTag($tag);

        return implode("\n", $lines);
    }
945370
protected function applyRule(ClassNode $node)
    {
        $implementedInterfaces = $this->getImplementedInterfaces($node);

        if ($implementedInterfaces->count() === 0 || !$this->hasFacadeInterface($node, $implementedInterfaces)) {
            $message = sprintf(
                'The %s is missing a "%sInterface" which violates the rule "%s"',
                $node->getImage(),
                $node->getImage(),
                static::RULE
            );

            $this->addViolation($node, [$message]);
        }
    }
540326
private function loadNode(\Twig_Node $node)
    {
        $formulae = array();

        if ($node instanceof AsseticNode) {
            $formulae[$node->getAttribute('name')] = array(
                $node->getAttribute('inputs'),
                $node->getAttribute('filters'),
                array(
                    'output'  => $node->getAttribute('asset')->getTargetPath(),
                    'name'    => $node->getAttribute('name'),
                    'debug'   => $node->getAttribute('debug'),
                    'combine' => $node->getAttribute('combine'),
                    'vars'    => $node->getAttribute('vars'),
                ),
            );
        } elseif ($node instanceof AsseticFilterNode) {
            $name = $node->getAttribute('name');

            $arguments = array();
            foreach ($node->getNode('arguments') as $argument) {
                $arguments[] = eval('return '.$this->twig->compile($argument).';');
            }

            $invoker = $this->twig->getExtension('Assetic\Extension\Twig\AsseticExtension')->getFilterInvoker($name);

            $inputs  = isset($arguments[0]) ? (array) $arguments[0] : array();
            $filters = $invoker->getFilters();
            $options = array_replace($invoker->getOptions(), isset($arguments[1]) ? $arguments[1] : array());

            if (!isset($options['name'])) {
                $options['name'] = $invoker->getFactory()->generateAssetName($inputs, $filters, $options);
            }

            $formulae[$options['name']] = array($inputs, $filters, $options);
        }

        foreach ($node as $child) {
            if ($child instanceof \Twig_Node) {
                $formulae += $this->loadNode($child);
            }
        }

        if ($node->hasAttribute('embedded_templates')) {
            foreach ($node->getAttribute('embedded_templates') as $child) {
                $formulae += $this->loadNode($child);
            }
        }

        return $formulae;
    }
822800
protected function compileMixinCall(Node $node)
    {

        $name = $node->name;
        $hasBlock = false;

        $interpolatedName = $this->interpolate($name, true);
        $interpolated = $name !== $interpolatedName;
        $name = $interpolatedName;

        if ($interpolated)
            $this->options['compile_uncalled_mixins'] = true;

        if (!$interpolated && !isset($this->mixins[$name]))
            $this->throwException(
                "A mixin with the name [$name] is not defined. Please define it with `mixin $name` before you attempt to call a it".
                "with that name.",
                $node
            );

        if (!$interpolated && !in_array($name, $this->calledMixins, true))
            $this->calledMixins[] = $name;

        $mixin = null;

        if (!$interpolated) {
            
            $mixin = $this->mixins[$name];

            if ($mixin instanceof Node) {
    
                //This is still an unhandled mixin, inside another mixin
                //Make sure to resolve circular references
                $this->handleMixin($mixin);
                $mixin = $this->mixins[$name];
            }
        }


        $phtml = '';

        if (count($node->children) > 0) {

            $hasBlock = true;
            $phtml = $this->createCode(
                '$__block = function(array $__scope) {
                    extract($__scope);
                '
            ).$this->newLine();
            $phtml .= $this->compileChildren($node->children, false).$this->newLine();
            $phtml .= $this->indent().$this->createCode('};').$this->newLine();
        }

        $nodeAttributes = $node->attributes;
        foreach ($node->assignments as $assignment) {

            $attrName = $assignment->name;

            //This line provides compatibility to the offical jade method
            if (($this->isHtml() || $this->isXml()) && $attrName === 'classes')
                $attrName = 'class';

            foreach ($assignment->attributes as $attr) {

                if (!$attr->value)
                    $attr->value = $attr->name;

                $attr->name = $attrName;
                $nodeAttributes[] = $attr;
            }
        }

        $args = [];
        $i = 0;
        foreach ($nodeAttributes as $index => $attr) {

            $value = $attr->value;

            if ($attr->name) {

                if (isset($args[$attr->name])) {

                    if (is_array($args[$attr->name]))
                        $args[$attr->name][] = $value;
                    else
                        $args[$attr->name] = [$args[$attr->name], $value];
                } else {

                    $args[$attr->name] = $value;
                }
                continue;
            }


                $mixinAttributes = !$interpolated ? $mixin['node']->attributes : null;

                if (!$interpolated && isset($mixinAttributes[$i]) && strncmp('...', $mixinAttributes[$i]->name, 3) !== 0) {

                    $args[$mixinAttributes[$i]->name] = $value;
                } else {

                    $args[] = $value;
                }
            $i++;
        }

        $phtml .= (count($node->children) > 0 ? $this->indent() : '').$this->createCode(
                '$__scope = \\Tale\\Jade\\Compiler\\create_scope(get_defined_vars()); '. 
                '$__mixinCallArgs = '.$this->exportArray($args).';'.(
                    $hasBlock ? '$__mixinCallArgs[\'__block\'] = isset($__block) ? $__block : null; ' : ''
                ).'call_user_func($__mixins[\''.$name.'\'], $__mixinCallArgs, $__scope); '.
                'unset($__scope); '.
                'unset($__mixinCallArgs); '.(
                    $hasBlock ? 'unset($__block); ' : ''
                )
            ).$this->newLine();

        return $phtml;
    }
1298484
public function enterNode(Node $node)
    {
        // @todo support MethodCall and StaticCall as well.
        if ($node instanceof FuncCall) {
            // if function name is an expression or a variable, give it a pass for now.
            if ($node->name instanceof Expr || $node->name instanceof Variable) {
                return;
            }

            $name = (string) $node->name;

            if ($name === 'array_multisort') {
                return $this->validateArrayMultisort($node);
            }

            try {
                $refl = new \ReflectionFunction($name);
            } catch (\ReflectionException $e) {
                // Well, we gave it a shot!
                return;
            }

            foreach ($refl->getParameters() as $key => $param) {
                if (\array_key_exists($key, $node->args)) {
                    $arg = $node->args[$key];
                    if ($param->isPassedByReference() && !$this->isPassableByReference($arg)) {
                        throw new FatalErrorException(self::EXCEPTION_MESSAGE, 0, E_ERROR, null, $node->getLine());
                    }
                }
            }
        }
    }
260744
public function enterNode(Node $node)
    {
        if (!$node instanceof Instanceof_) {
            return;
        }

        if (($node->expr instanceof Scalar && !$node->expr instanceof Encapsed) || $node->expr instanceof ConstFetch) {
            throw new FatalErrorException(self::EXCEPTION_MSG, 0, E_ERROR, null, $node->getLine());
        }
    }
273487
public function convertTableNodeToSingleContextClause(TableNode $node)
    {
        // Get all rows and extract the heading.
        $rows = $node->getRows();
        // Get rid of the top row as its just represents the title.
        unset($rows[0]);

        if (! $rows) {
            throw new \Exception('No data provided to loop through.');
        }

        $clauseArray = [];
        // Loop through the rest of the rows and form up the queries.
        foreach ($rows as $row) {
            $clauseArray[] = implode(':', $row);
        }

        return implode(',', $clauseArray);
    }
1300187
protected function getDeprecatedDocComment(Node $node)
    {
        try {
            $docBlock = new DocBlock((string) $node->getDocComment());
            /** @var DocBlock\Tag\DeprecatedTag[] $deprecatedTag */
            $deprecatedTag = $docBlock->getTagsByName('deprecated');

            if (0 === count($deprecatedTag)) {
                return;
            }

            $comment = $deprecatedTag[0]->getContent();

            return preg_replace('/[[:blank:]]+/', ' ', $comment);
        } catch (\Exception $e) {
            return;
        }
    }
1327163
private function getNodes($node)
    {
        $this->logger->info('[Get Nodes] Retrieving nodes...');

        $stripUnlikelyCandidates = $this->configuration->getStripUnlikelyCandidates();

        $elementsToScore = [];

        /*
         * First, node prepping. Trash nodes that look cruddy (like ones with the
         * class name "comment", etc), and turn divs into P tags where they have been
         * used inappropriately (as in, where they contain no other block level elements.)
         */

        while ($node) {
            // Remove DOMComments nodes as we don't need them and mess up children counting
            if ($node->nodeType === XML_COMMENT_NODE) {
                $this->logger->debug(sprintf('[Get Nodes] Found comment node, removing... Node content was: \'%s\'', substr($node->nodeValue, 0, 128)));
                $node = NodeUtility::removeAndGetNext($node);
                continue;
            }

            $matchString = $node->getAttribute('class') . ' ' . $node->getAttribute('id');

            if (!$node->isProbablyVisible()) {
                $this->logger->debug(sprintf('[Get Nodes] Removing hidden node... Match string was: \'%s\'', $matchString));
                $node = NodeUtility::removeAndGetNext($node);
                continue;
            }

            // Check to see if this node is a byline, and remove it if it is.
            if ($this->checkByline($node, $matchString)) {
                $this->logger->debug(sprintf('[Get Nodes] Found byline, removing... Node content was: \'%s\'', substr($node->nodeValue, 0, 128)));
                $node = NodeUtility::removeAndGetNext($node);
                continue;
            }

            // Remove unlikely candidates
            if ($stripUnlikelyCandidates) {
                if (
                    preg_match(NodeUtility::$regexps['unlikelyCandidates'], $matchString) &&
                    !preg_match(NodeUtility::$regexps['okMaybeItsACandidate'], $matchString) &&
                    $node->nodeName !== 'body' &&
                    $node->nodeName !== 'a'
                ) {
                    $this->logger->debug(sprintf('[Get Nodes] Removing unlikely candidate. Node content was: \'%s\'', substr($node->nodeValue, 0, 128)));
                    $node = NodeUtility::removeAndGetNext($node);
                    continue;
                }
            }

            // Remove DIV, SECTION, and HEADER nodes without any content(e.g. text, image, video, or iframe).
            if (($node->nodeName === 'div' || $node->nodeName === 'section' || $node->nodeName === 'header' ||
                    $node->nodeName === 'h1' || $node->nodeName === 'h2' || $node->nodeName === 'h3' ||
                    $node->nodeName === 'h4' || $node->nodeName === 'h5' || $node->nodeName === 'h6' ||
                    $node->nodeName === 'p') &&
                $node->isElementWithoutContent()) {
                $this->logger->debug(sprintf('[Get Nodes] Removing empty \'%s\' node.', $node->nodeName));
                $node = NodeUtility::removeAndGetNext($node);
                continue;
            }

            if (in_array(strtolower($node->nodeName), $this->defaultTagsToScore)) {
                $this->logger->debug(sprintf('[Get Nodes] Adding node to score list, node content is: \'%s\'', substr($node->nodeValue, 0, 128)));
                $elementsToScore[] = $node;
            }

            // Turn all divs that don't have children block level elements into p's
            if ($node->nodeName === 'div') {
                // Put phrasing content into paragraphs.
                $p = null;
                $childNode = $node->firstChild;
                while ($childNode) {
                    $nextSibling = $childNode->nextSibling;
                    if ($childNode->isPhrasingContent()) {
                        if ($p !== null) {
                            $p->appendChild($childNode);
                        } elseif (!$childNode->isWhitespace()) {
                            $p = $this->dom->createElement('p');
                            $node->replaceChild($p, $childNode);
                            $p->appendChild($childNode);
                        }
                    } elseif ($p !== null) {
                        while ($p->lastChild && $p->lastChild->isWhitespace()) {
                            $p->removeChild($p->lastChild);
                        }
                        $p = null;
                    }
                    $childNode = $nextSibling;
                }

                /*
                 * Sites like http://mobile.slate.com encloses each paragraph with a DIV
                 * element. DIVs with only a P element inside and no text content can be
                 * safely converted into plain P elements to avoid confusing the scoring
                 * algorithm with DIVs with are, in practice, paragraphs.
                 */
                if ($node->hasSingleTagInsideElement('p') && $node->getLinkDensity() < 0.25) {
                    $this->logger->debug(sprintf('[Get Nodes] Found DIV with a single P node, removing DIV. Node content is: \'%s\'', substr($node->nodeValue, 0, 128)));
                    $pNode = $node->getChildren(true)[0];
                    $node->parentNode->replaceChild($pNode, $node);
                    $node = $pNode;
                    $elementsToScore[] = $node;
                } elseif (!$node->hasSingleChildBlockElement()) {
                    $this->logger->debug(sprintf('[Get Nodes] Found DIV with a single child block element, converting to a P node. Node content is: \'%s\'', substr($node->nodeValue, 0, 128)));
                    $node = NodeUtility::setNodeTag($node, 'p');
                    $elementsToScore[] = $node;
                }
            }

            $node = NodeUtility::getNextNode($node);
        }

        return $elementsToScore;
    }
1169839
private function isIncludeThrowableNode(Node $node): bool
    {
        foreach ($node->children['class']->children as $class) {
            if ($class->children['name'] === 'Throwable') {
                return true;
            }
        }

        return false;
    }