standards = self::findConfiguration($path); // Autoload class to set up a bunch of PHP_CodeSniffer-specific token type constants spl_autoload_call(Tokens::class); $file = new DummyFile($content, new Ruleset($config), $config); $file->process(); $fixed = $file->fixer->fixFile(); if (!$fixed && $file->getErrorCount() > 0) { throw new Exception('Unable to format file'); } $new = $file->fixer->getContents(); if ($content === $new) { return []; } return [new TextEdit(new Range(new Position(0, 0), self::calculateEndPosition($content)), $new)]; } /** * Calculate position of last character. * * @param string $content document as string * * @return \LanguageServer\Protocol\Position */ private static function calculateEndPosition(string $content): Position { $lines = explode("\n", $content); return new Position(count($lines) - 1, strlen(end($lines))); } /** * Search for PHP_CodeSniffer configuration file at given directory or its parents. * If no configuration found then PSR2 standard is loaded by default. * * @param string $path path to file or directory * @return string[] */ private static function findConfiguration(string $path) { if (is_dir($path)) { $currentDir = $path; } else { $currentDir = dirname($path); } do { $default = $currentDir . DIRECTORY_SEPARATOR . 'phpcs.xml'; if (is_file($default)) { return [$default]; } $default = $currentDir . DIRECTORY_SEPARATOR . 'phpcs.xml.dist'; if (is_file($default)) { return [$default]; } $lastDir = $currentDir; $currentDir = dirname($currentDir); } while ($currentDir !== '.' && $currentDir !== $lastDir); $standard = Config::getConfigData('default_standard') ?? 'PSR2'; return explode(',', $standard); } }