diff --git a/composer.json b/composer.json index ee05937..2eef524 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,8 @@ "nikic/php-parser": "^3.0.0beta1", "phpdocumentor/reflection-docblock": "^3.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", "prefer-stable": true, diff --git a/fixtures/format.php b/fixtures/format.php index b45ebab..f300b67 100644 --- a/fixtures/format.php +++ b/fixtures/format.php @@ -1,13 +1,13 @@ 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); + } + +} diff --git a/src/PhpDocument.php b/src/PhpDocument.php index 6ba2900..82bd2cd 100644 --- a/src/PhpDocument.php +++ b/src/PhpDocument.php @@ -224,14 +224,11 @@ class PhpDocument */ public function getFormattedText() { - if (empty($this->stmts)) { + if (empty($this->getContent())) { return []; } - $prettyPrinter = new PrettyPrinter(); - $edit = new TextEdit(); - $edit->range = new Range(new Position(0, 0), new Position(PHP_INT_MAX, PHP_INT_MAX)); - $edit->newText = $prettyPrinter->prettyPrintFile($this->stmts); - return [$edit]; + $formatter = new Formatter(); + return $formatter->format($this->getContent(), $this->getUri()); } /** diff --git a/src/Protocol/TextEdit.php b/src/Protocol/TextEdit.php index c13a3c5..235737f 100644 --- a/src/Protocol/TextEdit.php +++ b/src/Protocol/TextEdit.php @@ -22,4 +22,10 @@ class TextEdit * @var string */ public $newText; + + public function __construct(Range $range = null, string $newText) + { + $this->range = $range; + $this->newText = $newText; + } } diff --git a/src/utils.php b/src/utils.php index 3086efd..848c286 100644 --- a/src/utils.php +++ b/src/utils.php @@ -32,3 +32,19 @@ function pathToUri(string $filepath): string { $filepath = implode('/', array_map('urlencode', explode('/', $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; +} diff --git a/tests/FormatterTest.php b/tests/FormatterTest.php new file mode 100644 index 0000000..f6ec790 --- /dev/null +++ b/tests/FormatterTest.php @@ -0,0 +1,32 @@ +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 == []); + } + +} \ No newline at end of file diff --git a/tests/Server/TextDocument/FormattingTest.php b/tests/Server/TextDocument/FormattingTest.php index 2dcc46e..06b45fc 100644 --- a/tests/Server/TextDocument/FormattingTest.php +++ b/tests/Server/TextDocument/FormattingTest.php @@ -22,9 +22,9 @@ class FormattingTest extends TestCase $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); $textDocument = new Server\TextDocument($project, $client); @@ -54,4 +54,14 @@ class FormattingTest extends TestCase 'newText' => $expected ]], 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)); + } } diff --git a/tests/Utils/FileUriTest.php b/tests/Utils/FileUriTest.php index 802f78b..4d45ede 100644 --- a/tests/Utils/FileUriTest.php +++ b/tests/Utils/FileUriTest.php @@ -33,4 +33,25 @@ class FileUriTest extends TestCase $uri = \LanguageServer\pathToUri('c:\\foo\\bar.baz'); $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)); + } }