private function lintPHP54Features(XHPASTNode $root) { $indexes = $root->selectDescendantsOfType('n_INDEX_ACCESS'); foreach ($indexes as $index) { switch ($index->getChildByIndex(0)->getTypeName()) { case 'n_FUNCTION_CALL': case 'n_METHOD_CALL': $this->raiseLintAtNode($index->getChildByIndex(1), pht('The `%s` syntax was not introduced until PHP 5.4, but this ' . 'codebase targets an earlier version of PHP. You can rewrite ' . 'this expression using `%s`.', 'f()[...]', 'idx()')); break; } } $literals = $root->selectDescendantsOftype('n_ARRAY_LITERAL'); foreach ($literals as $literal) { $open_token = head($literal->getTokens())->getValue(); if ($open_token == '[') { $this->raiseLintAtNode($literal, pht('The short array syntax ("[...]") was not introduced until ' . 'PHP 5.4, but this codebase targets an earlier version of PHP. ' . 'You can rewrite this expression using `array(...)` instead.')); } } $closures = $this->getAnonymousClosures($root); foreach ($closures as $closure) { $static_accesses = $closure->selectDescendantsOfType('n_CLASS_STATIC_ACCESS'); foreach ($static_accesses as $static_access) { $class = $static_access->getChildByIndex(0); if ($class->getTypeName() != 'n_CLASS_NAME') { continue; } if (strtolower($class->getConcreteString()) != 'self') { continue; } $this->raiseLintAtNode($class, pht('The use of `%s` in an anonymous closure is not ' . 'available before PHP 5.4.', 'self')); } $property_accesses = $closure->selectDescendantsOfType('n_OBJECT_PROPERTY_ACCESS'); foreach ($property_accesses as $property_access) { $variable = $property_access->getChildByIndex(0); if ($variable->getTypeName() != 'n_VARIABLE') { continue; } if ($variable->getConcreteString() != '$this') { continue; } $this->raiseLintAtNode($variable, pht('The use of `%s` in an anonymous closure is not ' . 'available before PHP 5.4.', '$this')); } } $numeric_scalars = $root->selectDescendantsOfType('n_NUMERIC_SCALAR'); foreach ($numeric_scalars as $numeric_scalar) { if (preg_match('/^0b[01]+$/i', $numeric_scalar->getConcreteString())) { $this->raiseLintAtNode($numeric_scalar, pht('Binary integer literals are not available before PHP 5.4.')); } } }