Skip to content

Commit c52e9c0

Browse files
authored
Adding line detector (#6)
* Adding line detector * Make CI green
1 parent 89edb6b commit c52e9c0

File tree

3 files changed

+74
-8
lines changed

3 files changed

+74
-8
lines changed

src/Issue/Issue.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,44 @@
22

33
namespace Symfony\CodeBlockChecker\Issue;
44

5+
use Doctrine\RST\Nodes\CodeNode;
6+
use Symfony\CodeBlockChecker\Service\LineDetector;
7+
58
/**
69
* Represent an error with some code.
710
*
811
* @author Tobias Nyholm <[email protected]>
912
*/
1013
class Issue implements \Stringable
1114
{
15+
private CodeNode $node;
1216
private string $text;
1317
private string $type;
1418
private string $file;
15-
private int $line;
1619

17-
public function __construct(string $text, string $type, string $file, int $line)
20+
/**
21+
* The line in the file.
22+
*/
23+
private ?int $line;
24+
25+
/**
26+
* The local line is inside the code node.
27+
*/
28+
private int $localLine;
29+
30+
public function __construct(CodeNode $node, string $text, string $type, string $file, int $localLine)
1831
{
32+
$this->node = $node;
1933
$this->text = $text;
2034
$this->type = $type;
2135
$this->file = $file;
22-
$this->line = $line;
36+
$this->localLine = $localLine;
37+
$this->line = null;
38+
}
39+
40+
public function getHash(): string
41+
{
42+
return sha1($this->node->getValue());
2343
}
2444

2545
public function getText(): string
@@ -39,6 +59,11 @@ public function getFile(): string
3959

4060
public function getLine(): int
4161
{
62+
if (null === $this->line) {
63+
$offset = LineDetector::find($this->node);
64+
$this->line = $offset + $this->localLine;
65+
}
66+
4267
return $this->line;
4368
}
4469

src/Listener/ValidCodeNodeListener.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ private function validatePhp(CodeNode $node)
7777
$text = str_replace($matches[0], '', $text);
7878
$line = (int) $matches[1];
7979
}
80-
$this->errorManager->addIssue(new Issue($text, 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), $line));
80+
$this->errorManager->addIssue(new Issue($node, $text, 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), $line));
8181
}
8282

8383
private function validateXml(CodeNode $node)
@@ -101,7 +101,7 @@ private function validateXml(CodeNode $node)
101101
return;
102102
}
103103

104-
$this->errorManager->addIssue(new Issue($e->getMessage(), 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), 0));
104+
$this->errorManager->addIssue(new Issue($node, $e->getMessage(), 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), 0));
105105
}
106106
}
107107

@@ -116,7 +116,7 @@ private function validateYaml(CodeNode $node)
116116
return;
117117
}
118118

119-
$this->errorManager->addIssue(new Issue($e->getMessage(), 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), 0));
119+
$this->errorManager->addIssue(new Issue($node, $e->getMessage(), 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), 0));
120120
}
121121
}
122122

@@ -132,7 +132,7 @@ private function validateTwig(CodeNode $node)
132132
// We cannot parse the TokenStream because we dont have all extensions loaded.
133133
$this->twig->parse($tokens);
134134
} catch (SyntaxError $e) {
135-
$this->errorManager->addIssue(new Issue($e->getMessage(), 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), 0));
135+
$this->errorManager->addIssue(new Issue($node, $e->getMessage(), 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), 0));
136136
}
137137
}
138138

@@ -141,7 +141,7 @@ private function validateJson(CodeNode $node)
141141
try {
142142
$data = json_decode($node->getValue(), true, 512, JSON_THROW_ON_ERROR);
143143
} catch (\JsonException $e) {
144-
$this->errorManager->addIssue(new Issue($e->getMessage(), 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), 0));
144+
$this->errorManager->addIssue(new Issue($node, $e->getMessage(), 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), 0));
145145
}
146146
}
147147
}

src/Service/LineDetector.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace Symfony\CodeBlockChecker\Service;
4+
5+
use Doctrine\RST\Nodes\CodeNode;
6+
7+
/**
8+
* Find the line a CodeNode belongs to.
9+
*
10+
* @author Tobias Nyholm <[email protected]>
11+
*/
12+
class LineDetector
13+
{
14+
/**
15+
* Get the line number where the $node starts.
16+
*/
17+
public static function find(CodeNode $node): int
18+
{
19+
$environment = $node->getEnvironment();
20+
if ('' === $environment->getCurrentFileName()) {
21+
return 0;
22+
}
23+
24+
$file = sprintf('%s/%s.rst', $environment->getCurrentDirectory(), $environment->getCurrentFileName());
25+
$contents = explode(PHP_EOL, file_get_contents($file));
26+
$codeBlock = explode(PHP_EOL, $node->getValue());
27+
28+
foreach ($contents as $i => $line) {
29+
foreach ($codeBlock as $j => $needle) {
30+
if (!str_contains($contents[$i + $j], $needle)) {
31+
continue 2;
32+
}
33+
}
34+
35+
// The file's first row is 1 and our arrays first index is 0.
36+
return $i + 1;
37+
}
38+
39+
return 0;
40+
}
41+
}

0 commit comments

Comments
 (0)