Use PHP_CodeSniffer as a formatter
parent
18ac760bc6
commit
6b03196b79
|
@ -27,7 +27,8 @@
|
||||||
"nikic/php-parser": "^3.0.0beta1",
|
"nikic/php-parser": "^3.0.0beta1",
|
||||||
"phpdocumentor/reflection-docblock": "^3.0",
|
"phpdocumentor/reflection-docblock": "^3.0",
|
||||||
"sabre/event": "^4.0",
|
"sabre/event": "^4.0",
|
||||||
"felixfbecker/advanced-json-rpc": "^1.2"
|
"felixfbecker/advanced-json-rpc": "^1.2",
|
||||||
|
"squizlabs/php_codesniffer" : "^2.7"
|
||||||
},
|
},
|
||||||
"minimum-stability": "dev",
|
"minimum-stability": "dev",
|
||||||
"prefer-stable": true,
|
"prefer-stable": true,
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace TestNamespace;
|
namespace TestNamespace;
|
||||||
|
|
||||||
|
use SomeNamespace\Goo;
|
||||||
|
|
||||||
|
|
||||||
|
class TestClass
|
||||||
|
|
||||||
class TestClass
|
|
||||||
{
|
{
|
||||||
public $testProperty;
|
public $testProperty;
|
||||||
|
|
||||||
public function testMethod($testParameter)
|
public function testMethod($testParameter)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,14 +2,18 @@
|
||||||
|
|
||||||
namespace TestNamespace;
|
namespace TestNamespace;
|
||||||
|
|
||||||
|
use SomeNamespace\Goo;
|
||||||
|
|
||||||
class TestClass
|
class TestClass
|
||||||
{
|
{
|
||||||
public $testProperty;
|
public $testProperty;
|
||||||
|
|
||||||
public function testMethod($testParameter)
|
public function testMethod($testParameter)
|
||||||
{
|
{
|
||||||
$testVariable = 123;
|
$testVariable = 123;
|
||||||
|
|
||||||
if (empty($testParameter)) {
|
if (empty($testParameter)) {
|
||||||
echo 'Empty';
|
echo 'Empty';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
<?php
|
||||||
|
namespace LanguageServer;
|
||||||
|
|
||||||
|
use LanguageServer\Protocol\{TextEdit, Range, Position, ErrorCode};
|
||||||
|
use AdvancedJsonRpc\ResponseError;
|
||||||
|
|
||||||
|
class Formatter
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param string $content
|
||||||
|
* @param string $uri
|
||||||
|
*
|
||||||
|
* @return \LanguageServer\Protocol\TextEdit[]
|
||||||
|
* @throws \AdvancedJsonRpc\ResponseError
|
||||||
|
*/
|
||||||
|
public function format(string $content, string $uri)
|
||||||
|
{
|
||||||
|
$path = uriToPath($uri);
|
||||||
|
$cs = new \PHP_CodeSniffer();
|
||||||
|
$cs->initStandard($this->findConfiguration($path));
|
||||||
|
$file = $cs->processFile(null, $content);
|
||||||
|
$fixed = $file->fixer->fixFile();
|
||||||
|
if (!$fixed && $file->getErrorCount() > 0) {
|
||||||
|
throw new ResponseError('Unable to format file', ErrorCode::INTERNAL_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
$new = $file->fixer->getContents();
|
||||||
|
if ($content === $new) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return [new TextEdit(new Range(new Position(0, 0), new Position(PHP_INT_MAX, PHP_INT_MAX)), $new)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param string $uri
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
private function findConfiguration(string $uri)
|
||||||
|
{
|
||||||
|
$currentDir = dirname($uri);
|
||||||
|
do {
|
||||||
|
$default = $currentDir . DIRECTORY_SEPARATOR . 'phpcs.xml';
|
||||||
|
if (is_file($default) === true) {
|
||||||
|
return array($default);
|
||||||
|
}
|
||||||
|
|
||||||
|
$default = $currentDir . DIRECTORY_SEPARATOR . 'phpcs.xml.dist';
|
||||||
|
if (is_file($default) === true) {
|
||||||
|
return array($default);
|
||||||
|
}
|
||||||
|
|
||||||
|
$lastDir = $currentDir;
|
||||||
|
$currentDir = dirname($currentDir);
|
||||||
|
} while ($currentDir !== '.' && $currentDir !== $lastDir);
|
||||||
|
|
||||||
|
$standard = \PHP_CodeSniffer::getConfigData('default_standard') ?? 'PSR2';
|
||||||
|
return explode(',', $standard);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -224,14 +224,11 @@ class PhpDocument
|
||||||
*/
|
*/
|
||||||
public function getFormattedText()
|
public function getFormattedText()
|
||||||
{
|
{
|
||||||
if (empty($this->stmts)) {
|
if (empty($this->getContent())) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
$prettyPrinter = new PrettyPrinter();
|
$formatter = new Formatter();
|
||||||
$edit = new TextEdit();
|
return $formatter->format($this->getContent(), $this->getUri());
|
||||||
$edit->range = new Range(new Position(0, 0), new Position(PHP_INT_MAX, PHP_INT_MAX));
|
|
||||||
$edit->newText = $prettyPrinter->prettyPrintFile($this->stmts);
|
|
||||||
return [$edit];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,4 +22,10 @@ class TextEdit
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $newText;
|
public $newText;
|
||||||
|
|
||||||
|
public function __construct(Range $range = null, string $newText)
|
||||||
|
{
|
||||||
|
$this->range = $range;
|
||||||
|
$this->newText = $newText;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,3 +32,19 @@ function pathToUri(string $filepath): string {
|
||||||
$filepath = implode('/', array_map('urlencode', explode('/', $filepath)));
|
$filepath = implode('/', array_map('urlencode', explode('/', $filepath)));
|
||||||
return 'file:///' . $filepath;
|
return 'file:///' . $filepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms URI into file path
|
||||||
|
*
|
||||||
|
* @param string $uri
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function uriToPath(string $uri)
|
||||||
|
{
|
||||||
|
$position = strpos($uri, '://');
|
||||||
|
if (! $position) {
|
||||||
|
return $uri;
|
||||||
|
}
|
||||||
|
$path = substr($uri, $position + 3);
|
||||||
|
return strpos($path, ':') ? str_replace('/', "\\", substr($path, 1)) : $path;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace LanguageServer\Tests\Server;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use LanguageServer\Formatter;
|
||||||
|
|
||||||
|
class FormatterTest extends TestCase
|
||||||
|
{
|
||||||
|
|
||||||
|
public function testFormat()
|
||||||
|
{
|
||||||
|
$formatter = new Formatter();
|
||||||
|
|
||||||
|
$input = file_get_contents(__DIR__ . '/../fixtures/format.php');
|
||||||
|
$output = file_get_contents(__DIR__ . '/../fixtures/format_expected.php');
|
||||||
|
|
||||||
|
$edits = $formatter->format($input, "whatever");
|
||||||
|
$this->assertTrue($edits[0]->newText === $output);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFormatNoChange()
|
||||||
|
{
|
||||||
|
$formatter = new Formatter();
|
||||||
|
$expected = file_get_contents(__DIR__ . '/../fixtures/format_expected.php');
|
||||||
|
|
||||||
|
$edits = $formatter->format($expected, "whatever");
|
||||||
|
$this->assertTrue($edits == []);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -22,9 +22,9 @@ class FormattingTest extends TestCase
|
||||||
$this->textDocument = new Server\TextDocument($project, $client);
|
$this->textDocument = new Server\TextDocument($project, $client);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test()
|
public function testFormatting()
|
||||||
{
|
{
|
||||||
$client = new LanguageClient(new MockProtocolStream());
|
$client = new LanguageClient(new MockProtocolStream());
|
||||||
$project = new Project($client);
|
$project = new Project($client);
|
||||||
$textDocument = new Server\TextDocument($project, $client);
|
$textDocument = new Server\TextDocument($project, $client);
|
||||||
|
|
||||||
|
@ -54,4 +54,14 @@ class FormattingTest extends TestCase
|
||||||
'newText' => $expected
|
'newText' => $expected
|
||||||
]], json_decode(json_encode($result), true));
|
]], json_decode(json_encode($result), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testFormattingInvalidUri()
|
||||||
|
{
|
||||||
|
$client = new LanguageClient(new MockProtocolStream());
|
||||||
|
$project = new Project($client);
|
||||||
|
$textDocument = new Server\TextDocument($project, $client);
|
||||||
|
|
||||||
|
$result = $textDocument->formatting(new TextDocumentIdentifier('whatever'), new FormattingOptions());
|
||||||
|
$this->assertEquals([], json_decode(json_encode($result), true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,4 +33,25 @@ class FileUriTest extends TestCase
|
||||||
$uri = \LanguageServer\pathToUri('c:\\foo\\bar.baz');
|
$uri = \LanguageServer\pathToUri('c:\\foo\\bar.baz');
|
||||||
$this->assertEquals('file:///c%3A/foo/bar.baz', $uri);
|
$this->assertEquals('file:///c%3A/foo/bar.baz', $uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testUriToPathUnix()
|
||||||
|
{
|
||||||
|
$uri = "file:///home/foo/bar/Test.php";
|
||||||
|
$this->assertEquals("/home/foo/bar/Test.php", \LanguageServer\uriToPath($uri));
|
||||||
|
|
||||||
|
$uri = "/home/foo/bar/Test.php";
|
||||||
|
$this->assertEquals("/home/foo/bar/Test.php", \LanguageServer\uriToPath($uri));
|
||||||
|
|
||||||
|
$uri = "/home/foo space/bar/Test.php";
|
||||||
|
$this->assertEquals("/home/foo space/bar/Test.php", \LanguageServer\uriToPath($uri));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUriToPathWindows()
|
||||||
|
{
|
||||||
|
$uri = "file:///c:/home/foo/bar/Test.php";
|
||||||
|
$this->assertEquals("c:\\home\\foo\\bar\\Test.php", \LanguageServer\uriToPath($uri));
|
||||||
|
|
||||||
|
$uri = "c:\\home\\foo\\bar\\Test.php";
|
||||||
|
$this->assertEquals("c:\\home\\foo\\bar\\Test.php", \LanguageServer\uriToPath($uri));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue