function DebugClassLoader::patchMethod
Utility method to add
Return value
annotations to the Symfony code-base where it triggers self-deprecations.
1 call to DebugClassLoader::patchMethod()
- DebugClassLoader::checkAnnotations in vendor/
symfony/ error-handler/ DebugClassLoader.php
File
-
vendor/
symfony/ error-handler/ DebugClassLoader.php, line 987
Class
- DebugClassLoader
- Autoloader checking if the class is really defined in the file found.
Namespace
Symfony\Component\ErrorHandlerCode
private function patchMethod(\ReflectionMethod $method, string $returnType, string $declaringFile, string $normalizedType) : void {
static $patchedMethods = [];
static $useStatements = [];
if (!is_file($file = $method->getFileName()) || isset($patchedMethods[$file][$startLine = $method->getStartLine()])) {
return;
}
$patchedMethods[$file][$startLine] = true;
$fileOffset = self::$fileOffsets[$file] ?? 0;
$startLine += $fileOffset - 2;
if ($nullable = str_ends_with($returnType, '|null')) {
$returnType = substr($returnType, 0, -5);
}
$glue = str_contains($returnType, '&') ? '&' : '|';
$returnType = explode($glue, $returnType);
$code = file($file);
foreach ($returnType as $i => $type) {
if (preg_match('/((?:\\[\\])+)$/', $type, $m)) {
$type = substr($type, 0, -\strlen($m[1]));
$format = '%s' . $m[1];
}
else {
$format = null;
}
if (isset(self::SPECIAL_RETURN_TYPES[$type]) || '\\' === $type[0] && !($p = strrpos($type, '\\', 1))) {
continue;
}
[
$namespace,
$useOffset,
$useMap,
] = $useStatements[$file] ??= self::getUseStatements($file);
if ('\\' !== $type[0]) {
[
$declaringNamespace,
,
$declaringUseMap,
] = $useStatements[$declaringFile] ??= self::getUseStatements($declaringFile);
$p = strpos($type, '\\', 1);
$alias = $p ? substr($type, 0, $p) : $type;
if (isset($declaringUseMap[$alias])) {
$type = '\\' . $declaringUseMap[$alias] . ($p ? substr($type, $p) : '');
}
else {
$type = '\\' . $declaringNamespace . $type;
}
$p = strrpos($type, '\\', 1);
}
$alias = substr($type, 1 + $p);
$type = substr($type, 1);
if (!isset($useMap[$alias]) && (class_exists($c = $namespace . $alias) || interface_exists($c) || trait_exists($c))) {
$useMap[$alias] = $c;
}
if (!isset($useMap[$alias])) {
$useStatements[$file][2][$alias] = $type;
$code[$useOffset] = "use {$type};\n" . $code[$useOffset];
++$fileOffset;
}
elseif ($useMap[$alias] !== $type) {
$alias .= 'FIXME';
$useStatements[$file][2][$alias] = $type;
$code[$useOffset] = "use {$type} as {$alias};\n" . $code[$useOffset];
++$fileOffset;
}
$returnType[$i] = null !== $format ? \sprintf($format, $alias) : $alias;
}
if ('docblock' === $this->patchTypes['force'] || 'object' === $normalizedType && '7.1' === $this->patchTypes['php']) {
$returnType = implode($glue, $returnType) . ($nullable ? '|null' : '');
if (str_contains($code[$startLine], '#[')) {
--$startLine;
}
if ($method->getDocComment()) {
$code[$startLine] = " * @return {$returnType}\n" . $code[$startLine];
}
else {
$code[$startLine] .= <<<EOTXT
/**
* @return {<span class="php-variable">$returnType</span>}
*/
EOTXT;
}
$fileOffset += substr_count($code[$startLine], "\n") - 1;
}
self::$fileOffsets[$file] = $fileOffset;
file_put_contents($file, $code);
$this->fixReturnStatements($method, $normalizedType);
}