1
0
Fork 0

Use PHP_CodeSniffer as a formatter

pull/35/head
Michal Niewrzal 2016-09-30 13:08:52 +02:00 committed by Felix Becker
parent 18ac760bc6
commit 6b03196b79
10 changed files with 165 additions and 15 deletions

View File

@ -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,

View File

@ -2,7 +2,7 @@
namespace TestNamespace; namespace TestNamespace;
use SomeNamespace\Goo;
class TestClass class TestClass

View File

@ -2,12 +2,16 @@
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';
} }

63
src/Formatter.php Normal file
View File

@ -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);
}
}

View File

@ -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];
} }
/** /**

View File

@ -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;
}
} }

View File

@ -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;
}

32
tests/FormatterTest.php Normal file
View File

@ -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 == []);
}
}

View File

@ -22,7 +22,7 @@ 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);
@ -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));
}
} }

View File

@ -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));
}
} }