private function ThemeFunctionDeprecationAnalyzer::analyzeFunction in Upgrade Status 8.3
Same name and namespace in other branches
- 8.2 src/ThemeFunctionDeprecationAnalyzer.php \Drupal\upgrade_status\ThemeFunctionDeprecationAnalyzer::analyzeFunction()
Analyzes function for definition of theme functions.
This doesn't recognize functions in all edge cases. For example, theme functions could be generated dynamically in a number of different ways. However, this will be useful in most use cases.
Parameters
$function: The function to be analyzed.
\Drupal\Core\Extension\Extension $extension: The extension that is being tested.
Return value
\Drupal\upgrade_status\DeprecationMessage[]
1 call to ThemeFunctionDeprecationAnalyzer::analyzeFunction()
- ThemeFunctionDeprecationAnalyzer::analyze in src/
ThemeFunctionDeprecationAnalyzer.php - Analyzes theme functions in an extension.
File
- src/
ThemeFunctionDeprecationAnalyzer.php, line 102
Class
- ThemeFunctionDeprecationAnalyzer
- A theme function deprecation analyzer.
Namespace
Drupal\upgrade_statusCode
private function analyzeFunction(string $function, Extension $extension) : array {
$deprecation_messages = [];
try {
$function_reflection = new \ReflectionFunction($function);
} catch (\ReflectionException $e) {
// Not all extensions implement theme hooks.
return [];
}
$parser = (new ParserFactory())
->create(ParserFactory::PREFER_PHP7);
try {
$ast = $parser
->parse(file_get_contents($function_reflection
->getFileName()));
} catch (Error $error) {
// The function cannot be evaluated because of a syntax error.
$deprecation_messages[] = new DeprecationMessage(sprintf('Parse error while processing the %s hook implementation.', $theme_function), $function_reflection
->getFileName(), $node
->getStartLine());
}
if (!is_iterable($ast)) {
return [];
}
$finder = new NodeFinder();
// Find the node for the function that is being analyzed.
$function_node = $finder
->findFirst($ast, function (Node $node) use ($function) {
return $node instanceof Function_ && isset($node->name) && $node->name->name === $function;
});
if (!$function_node) {
// This should never happen because the file has been loaded based on the
// existence of the function.
return [];
}
// Find theme functions that have been defined using the array syntax.
// @code
// function hook_theme() {
// return [
// 'theme_hook' => ['function' => theme_function'],
// ];
// }
// @endcode
$theme_function_nodes = $finder
->find([
$function_node,
], function (Node $node) {
return $node instanceof ArrayItem && $node->key instanceof String_ && $node->key->value === 'function';
});
foreach ($theme_function_nodes as $node) {
$theme_function = $node->value instanceof String_ ? sprintf('"%s"', $node->value->value) : 'an unknown';
$deprecation_messages[] = new DeprecationMessage(sprintf('The %s is defining %s theme function. Theme functions are deprecated. For more info, see https://www.drupal.org/node/2575445.', $extension
->getType(), $theme_function), $function_reflection
->getFileName(), $node
->getStartLine());
}
// Find theme functions that are being added to an existing array using
// the array square bracket syntax.
// @code
// function hook_theme_registry_alter(&$theme_registry) {
// $theme_registry['theme_hook']['function'] = 'another_theme_function';
// }
// @endcode
$theme_function_dim_nodes = $finder
->find([
$function_node,
], function (Node $node) {
return $node instanceof Assign && $node->var instanceof ArrayDimFetch && $node->var->dim instanceof String_ && $node->var->dim->value === 'function';
});
foreach ($theme_function_dim_nodes as $node) {
$theme_function = $node->expr instanceof String_ ? sprintf('"%s"', $node->expr->value) : 'an unknown';
$deprecation_messages[] = new DeprecationMessage(sprintf('The %s is defining %s theme function. Theme functions are deprecated. For more info, see https://www.drupal.org/node/2575445.', $extension
->getType(), $theme_function), $function_reflection
->getFileName(), $node
->getStartLine());
}
return $deprecation_messages;
}