Skip to content

Commit a4662a6

Browse files
committed
Match sniff PHP with its XML doc; ensure unique URLs after merge
1 parent 2a90da9 commit a4662a6

10 files changed

+308
-117
lines changed

src/Generator/Generator.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ interface Generator
1010
{
1111
public function getViolation(Violation $doc): string;
1212

13-
public function fromSniff(Sniff $doc): string;
13+
public function createSniffDoc(Sniff $sniff): string;
1414
}

src/Generator/MarkdownGenerator.php

+77-53
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use App\Value\Property;
88
use App\Value\Sniff;
99
use App\Value\Url;
10+
use App\Value\Urls;
1011
use App\Value\Violation;
1112
use Stringy\Stringy;
1213
use function Stringy\create as s;
@@ -17,19 +18,84 @@ public function __construct()
1718
{
1819
}
1920

20-
public function fromSniff(Sniff $doc): string
21+
public function createSniffDoc(Sniff $sniff): string
2122
{
2223
return <<<MD
23-
# {$doc->getCode()}
24+
# {$sniff->getCode()}
2425
25-
{$doc->getDocblock()}
26+
{$this->getDescription($sniff)}
27+
{$this->getDocblock($sniff)}
28+
{$this->getComparisons($sniff->getDiffs())}
29+
{$this->getPublicProperties($sniff->getProperties())}
30+
{$this->getSeeAlso($sniff->getLinks())}
31+
{$this->getViolations($sniff->getViolations())}
32+
MD;
33+
}
34+
35+
private function getDescription(Sniff $sniff): string
36+
{
37+
return <<<MD
38+
{$sniff->getDescription()}
2639
27-
{$this->getPublicProperties($doc->getProperties())}
28-
{$this->getSeeAlso($doc->getLinks())}
29-
{$this->getViolations($doc->getViolations())}
3040
MD;
3141
}
3242

43+
private function getDocblock(Sniff $sniff): string
44+
{
45+
if ($sniff->getDocblock() === '') {
46+
return '';
47+
}
48+
49+
return <<<MD
50+
## Docblock
51+
52+
{$sniff->getDocblock()}
53+
MD;
54+
}
55+
56+
/**
57+
* @param Diff[] $diffs
58+
*/
59+
private function getComparisons(array $diffs): string
60+
{
61+
if ($diffs === []) {
62+
return '';
63+
}
64+
65+
$diffBlocks = implode("\n\n", $this->getDiffBlocks($diffs));
66+
67+
return <<<MD
68+
## Comparisons
69+
70+
{$diffBlocks}
71+
MD;
72+
}
73+
74+
/**
75+
* @param Diff[] $diffs
76+
* @return string[]
77+
*/
78+
private function getDiffBlocks(array $diffs): array
79+
{
80+
return array_map(function (Diff $diff): string {
81+
return <<<MD
82+
```diff
83+
{$this->prependLinesWith('-', $diff->getBefore())}
84+
{$this->prependLinesWith('+', $diff->getAfter())}
85+
```
86+
MD;
87+
}, $diffs);
88+
}
89+
90+
private function prependLinesWith(string $prefix, string $lines): string
91+
{
92+
$prependedLines = array_map(function (Stringy $line) use ($prefix) {
93+
return (string)$line->prepend($prefix);
94+
}, s($lines)->lines());
95+
96+
return implode("\n", $prependedLines);
97+
}
98+
3399
/**
34100
* @param Property[] $properties
35101
*/
@@ -61,10 +127,9 @@ private function getPublicPropertyLines(array $properties): array
61127
}
62128

63129
/**
64-
* @param Url[] $links
65130
* @return string
66131
*/
67-
private function getSeeAlso(array $links): string
132+
private function getSeeAlso(Urls $links): string
68133
{
69134
if ($links === []) {
70135
return '';
@@ -81,14 +146,13 @@ private function getSeeAlso(array $links): string
81146
}
82147

83148
/**
84-
* @param Url[] $links
85149
* @return string[]
86150
*/
87-
private function getLinkLines(array $links): array
151+
private function getLinkLines(Urls $links): array
88152
{
89153
return array_map(function (Url $url) {
90154
return "- [$url]($url)";
91-
}, $links);
155+
}, $links->getUrls());
92156
}
93157

94158
/**
@@ -134,49 +198,9 @@ public function getViolation(Violation $doc): string
134198
return <<<MD
135199
{$doc->getDescription()}
136200
137-
{$this->getComparisons($doc)}
138-
{$this->getSeeAlso($doc->getLinks())}
139-
MD;
140-
}
141-
142-
private function getComparisons(Violation $doc): string
143-
{
144-
if ($doc->getDiffs() === []) {
145-
return '';
146-
}
147-
148-
$diffBlocks = implode("\n\n", $this->getDiffBlocks($doc->getDiffs()));
149-
150-
return <<<MD
151-
## Comparisons
152-
153-
{$diffBlocks}
201+
{$this->getComparisons($doc->getDiffs())}
154202
203+
{$this->getSeeAlso($doc->getLinks())}
155204
MD;
156205
}
157-
158-
/**
159-
* @param Diff[] $diffs
160-
* @return string[]
161-
*/
162-
private function getDiffBlocks(array $diffs): array
163-
{
164-
return array_map(function (Diff $diff): string {
165-
return <<<MD
166-
```diff
167-
{$this->prependLinesWith('-', $diff->getBefore())}
168-
{$this->prependLinesWith('+', $diff->getAfter())}
169-
```
170-
MD;
171-
}, $diffs);
172-
}
173-
174-
private function prependLinesWith(string $prefix, string $lines): string
175-
{
176-
$prependedLines = array_map(function (Stringy $line) use ($prefix) {
177-
return (string)$line->prepend($prefix);
178-
}, s($lines)->lines());
179-
180-
return implode("\n", $prependedLines);
181-
}
182206
}

src/Parser/SniffParser.php

+63-8
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
namespace App\Parser;
55

66
use App\Parser\Exception\NotASniffPath;
7+
use App\Value\Diff;
78
use App\Value\Property;
89
use App\Value\Sniff;
910
use App\Value\Url;
11+
use App\Value\Urls;
1012
use phpDocumentor\Reflection\DocBlock\Tags\Var_;
1113
use phpDocumentor\Reflection\DocBlockFactory;
1214
use ReflectionProperty;
@@ -15,24 +17,75 @@
1517
use Roave\BetterReflection\Reflection\ReflectionClass;
1618
use Roave\BetterReflection\Reflector\ClassReflector;
1719
use Roave\BetterReflection\SourceLocator\Type\SingleFileSourceLocator;
20+
use SimpleXMLElement;
21+
use function Stringy\create as s;
1822

1923
class SniffParser
2024
{
21-
public function parse(string $filePath): Sniff
25+
public function parse(string $phpFilePath): Sniff
2226
{
2327
$astLocator = (new BetterReflection())->astLocator();
24-
$reflector = new ClassReflector(new SingleFileSourceLocator($filePath, $astLocator));
28+
$reflector = new ClassReflector(new SingleFileSourceLocator($phpFilePath, $astLocator));
2529
$classInfo = $reflector->getAllClasses()[0];
2630

31+
$xmlUrls = [];
32+
$description = '';
33+
$diffs = [];
34+
$xmlFilePath = str_replace(['/Sniffs/', '.php'], ['/Docs/', '.xml'], $phpFilePath);
35+
if (file_exists($xmlFilePath)) {
36+
$xml = new SimpleXMLElement(file_get_contents($xmlFilePath));
37+
$xmlUrls = $this->getXmlUrls($xml);
38+
$description = $this->getDescription($xml);
39+
$diffs = $this->getDiffs($xml);
40+
}
41+
2742
return new Sniff(
28-
$this->getCode($filePath),
43+
$this->getCode($phpFilePath),
2944
$this->getDocBlock($classInfo->getDocComment()),
3045
$this->getProperties($classInfo),
31-
$this->getLinks($classInfo),
46+
$this->getLinks($classInfo, $xmlUrls),
47+
$description,
48+
$diffs,
3249
[]
3350
);
3451
}
3552

53+
/**
54+
* @return Url[]
55+
*/
56+
private function getXmlUrls(SimpleXMLElement $xml): array
57+
{
58+
$links = [];
59+
foreach ($xml->link as $link) {
60+
$links[] = new Url(
61+
(string)s((string)$link)->trim()
62+
);
63+
}
64+
65+
return $links;
66+
}
67+
68+
private function getDescription(SimpleXMLElement $xml): string
69+
{
70+
return (string)s((string)$xml->standard)->trim();
71+
}
72+
73+
/**
74+
* @return Diff[]
75+
*/
76+
private function getDiffs(SimpleXMLElement $xml): array
77+
{
78+
$comparisons = [];
79+
foreach ($xml->code_comparison as $comparison) {
80+
$comparisons[] = new Diff(
81+
(string)s((string)$comparison->code[1])->trim(),
82+
(string)s((string)$comparison->code[0])->trim(),
83+
);
84+
}
85+
86+
return $comparisons;
87+
}
88+
3689
private function getCode(string $filePath): string
3790
{
3891
$part = '([^\/]*)';
@@ -110,20 +163,22 @@ private function getPropertyDescription(Roave\ReflectionProperty $property): str
110163
}
111164

112165
/**
113-
* @return Url[]
166+
* @param Url[] $xmlUrls
114167
*/
115-
private function getLinks(ReflectionClass $classInfo): array
168+
private function getLinks(ReflectionClass $classInfo, array $xmlUrls): Urls
116169
{
117170
if ($classInfo->getDocComment() === '') {
118-
return [];
171+
return new Urls([]);
119172
}
120173

121174
$links = DocBlockFactory::createInstance()
122175
->create($classInfo->getDocComment())
123176
->getTagsByName('link');
124177

125-
return array_map(function (string $url) {
178+
$urls = array_map(function (string $url) {
126179
return new Url($url);
127180
}, $links);
181+
182+
return new Urls(array_merge($urls, $xmlUrls));
128183
}
129184
}

src/Parser/ViolationParser.php

+17-23
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,48 @@
66
use App\Parser\Exception\NotAViolationPath;
77
use App\Value\Diff;
88
use App\Value\Url;
9+
use App\Value\Urls;
910
use App\Value\Violation;
1011
use SimpleXMLElement;
1112
use function Stringy\create as s;
1213

1314
class ViolationParser
1415
{
15-
public function parse(string $filePath): Violation
16+
public function parse(string $xmlFilePath): Violation
1617
{
17-
$doc = new SimpleXMLElement(file_get_contents($filePath));
18+
$xml = new SimpleXMLElement(file_get_contents($xmlFilePath));
1819

1920
return new Violation(
20-
$this->getErrorCode($filePath),
21-
$this->getDescription($doc),
22-
$this->getDiffs($doc),
23-
$this->getLinks($doc)
21+
$this->getErrorCode($xmlFilePath),
22+
$this->getDescription($xml),
23+
$this->getDiffs($xml),
24+
$this->getLinks($xml)
2425
);
2526
}
2627

27-
private function getErrorCode(string $filePath): string
28+
private function getErrorCode(string $xmlFilePath): string
2829
{
2930
$part = '([^\/]*)';
30-
preg_match("/$part\/Docs\/$part\/$part\/$part.xml/", $filePath, $matches);
31+
preg_match("/$part\/Docs\/$part\/$part\/$part.xml/", $xmlFilePath, $matches);
3132
if ($matches === []) {
32-
throw NotAViolationPath::fromPath($filePath);
33+
throw NotAViolationPath::fromPath($xmlFilePath);
3334
}
3435

3536
return sprintf('%s.%s.%s.%s', $matches[1], $matches[2], $matches[3], $matches[4]);
3637
}
3738

38-
private function getDescription(SimpleXMLElement $doc): string
39+
private function getDescription(SimpleXMLElement $xml): string
3940
{
40-
return (string)s((string)$doc->standard)->trim();
41+
return (string)s((string)$xml->standard)->trim();
4142
}
4243

4344
/**
4445
* @return Diff[]
4546
*/
46-
private function getDiffs(SimpleXMLElement $doc): array
47+
private function getDiffs(SimpleXMLElement $xml): array
4748
{
4849
$comparisons = [];
49-
foreach ($doc->code_comparison as $comparison) {
50+
foreach ($xml->code_comparison as $comparison) {
5051
$comparisons[] = new Diff(
5152
(string)s((string)$comparison->code[1])->trim(),
5253
(string)s((string)$comparison->code[0])->trim(),
@@ -56,22 +57,15 @@ private function getDiffs(SimpleXMLElement $doc): array
5657
return $comparisons;
5758
}
5859

59-
/**
60-
* @return Url[]
61-
*/
62-
private function getLinks(SimpleXMLElement $doc): array
60+
private function getLinks(SimpleXMLElement $xml): Urls
6361
{
64-
if (count($doc->links) === 0) {
65-
return [];
66-
}
67-
6862
$links = [];
69-
foreach ($doc->links[0]->link as $link) {
63+
foreach ($xml->link as $link) {
7064
$links[] = new Url(
7165
(string)s((string)$link)->trim()
7266
);
7367
}
7468

75-
return $links;
69+
return new Urls($links);
7670
}
7771
}

0 commit comments

Comments
 (0)