Skip to content

Commit 1f808c5

Browse files
kaloyan-raevfelixfbecker
authored andcommitted
Fixes #59: Handle correctly negative endLine in PHP Parser errors (#62)
* Fixes #59: Handle correctly negative endLine in PHP Parser errors * Clearer $startLine calculation * Add missing test file * Better calculation of endLine * Remove trailing spaces
1 parent e75c159 commit 1f808c5

File tree

3 files changed

+48
-20
lines changed

3 files changed

+48
-20
lines changed

fixtures/namespace_not_first.php

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
3+
echo "Hello";
4+
5+
namespace A;

src/PhpDocument.php

+5-4
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,11 @@ public function parse()
176176
$diagnostics = [];
177177
foreach ($errors as $error) {
178178
$diagnostic = new Diagnostic();
179-
$diagnostic->range = new Range(
180-
new Position($error->getStartLine() - 1, $error->hasColumnInfo() ? $error->getStartColumn($this->content) - 1 : 0),
181-
new Position($error->getEndLine() - 1, $error->hasColumnInfo() ? $error->getEndColumn($this->content) : 0)
182-
);
179+
$startLine = max($error->getStartLine() - 1, 0);
180+
$startColumn = $error->hasColumnInfo() ? $error->getStartColumn($this->content) - 1 : 0;
181+
$endLine = max($error->getEndLine() - 1, $startLine);
182+
$endColumn = $error->hasColumnInfo() ? $error->getEndColumn($this->content) : 0;
183+
$diagnostic->range = new Range(new Position($startLine, $startColumn), new Position($endLine, $endColumn));
183184
$diagnostic->severity = DiagnosticSeverity::ERROR;
184185
$diagnostic->source = 'php';
185186
// Do not include "on line ..." in the error message

tests/Server/TextDocument/ParseErrorsTest.php

+38-16
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,12 @@ class ParseErrorsTest extends TestCase
1515
*/
1616
private $textDocument;
1717

18-
public function setUp()
19-
{
20-
$client = new LanguageClient(new MockProtocolStream());
21-
$project = new Project($client);
22-
$this->textDocument = new Server\TextDocument($project, $client);
23-
}
18+
private $args;
2419

25-
public function testParseErrorsArePublishedAsDiagnostics()
20+
public function setUp()
2621
{
27-
$args = null;
2822
$client = new LanguageClient(new MockProtocolStream());
29-
$client->textDocument = new class($args) extends Client\TextDocument {
23+
$client->textDocument = new class($this->args) extends Client\TextDocument {
3024
private $args;
3125
public function __construct(&$args)
3226
{
@@ -38,18 +32,22 @@ public function publishDiagnostics(string $uri, array $diagnostics)
3832
$this->args = func_get_args();
3933
}
4034
};
41-
4235
$project = new Project($client);
36+
$this->textDocument = new Server\TextDocument($project, $client);
37+
}
4338

44-
$textDocument = new Server\TextDocument($project, $client);
45-
46-
// Trigger parsing of source
39+
private function openFile($file) {
4740
$textDocumentItem = new TextDocumentItem();
4841
$textDocumentItem->uri = 'whatever';
4942
$textDocumentItem->languageId = 'php';
5043
$textDocumentItem->version = 1;
51-
$textDocumentItem->text = file_get_contents(__DIR__ . '/../../../fixtures/invalid_file.php');
52-
$textDocument->didOpen($textDocumentItem);
44+
$textDocumentItem->text = file_get_contents($file);
45+
$this->textDocument->didOpen($textDocumentItem);
46+
}
47+
48+
public function testParseErrorsArePublishedAsDiagnostics()
49+
{
50+
$this->openFile(__DIR__ . '/../../../fixtures/invalid_file.php');
5351
$this->assertEquals([
5452
'whatever',
5553
[[
@@ -68,6 +66,30 @@ public function publishDiagnostics(string $uri, array $diagnostics)
6866
'source' => 'php',
6967
'message' => "Syntax error, unexpected T_CLASS, expecting T_STRING"
7068
]]
71-
], json_decode(json_encode($args), true));
69+
], json_decode(json_encode($this->args), true));
70+
}
71+
72+
public function testParseErrorsWithOnlyStartLine()
73+
{
74+
$this->openFile(__DIR__ . '/../../../fixtures/namespace_not_first.php');
75+
$this->assertEquals([
76+
'whatever',
77+
[[
78+
'range' => [
79+
'start' => [
80+
'line' => 4,
81+
'character' => 0
82+
],
83+
'end' => [
84+
'line' => 4,
85+
'character' => 0
86+
]
87+
],
88+
'severity' => DiagnosticSeverity::ERROR,
89+
'code' => null,
90+
'source' => 'php',
91+
'message' => "Namespace declaration statement has to be the very first statement in the script"
92+
]]
93+
], json_decode(json_encode($this->args), true));
7294
}
7395
}

0 commit comments

Comments
 (0)