-
Notifications
You must be signed in to change notification settings - Fork 9
OPSRC-505 Support for Twigcs #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 12 commits
b58a011
4bdd781
f39948c
178ffc5
d3860f3
f071a8b
06c7575
c77b881
5b4212b
639093b
c6dbbcb
2816b95
6d4cde0
1ed025d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| <?php | ||
|
|
||
| /* | ||
| * This file has been created by developers from BitBag. | ||
| * Feel free to contact us once you face any issues or want to start | ||
| * You can find more information about us on https://bitbag.io and write us | ||
| * an email on hello@bitbag.io. | ||
| */ | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace BitBag\CodingStandard\Twigcs\Dto; | ||
|
|
||
| final class HtmlTagDto | ||
| { | ||
| /** @var string */ | ||
| private $tag = ''; | ||
|
|
||
| /** @var string */ | ||
| private $html = ''; | ||
|
|
||
| /** @var int */ | ||
| private $offset = 0; | ||
|
|
||
| public function getTag(): string | ||
| { | ||
| return $this->tag; | ||
| } | ||
|
|
||
| public function setTag(string $tag): self | ||
| { | ||
| $this->tag = $tag; | ||
|
|
||
| return $this; | ||
| } | ||
|
|
||
| public function getHtml(): string | ||
| { | ||
| return $this->html; | ||
| } | ||
|
|
||
| public function setHtml(string $html): self | ||
| { | ||
| $this->html = $html; | ||
|
|
||
| return $this; | ||
| } | ||
|
|
||
| public function getOffset(): int | ||
| { | ||
| return $this->offset; | ||
| } | ||
|
|
||
| public function setOffset(int $offset): self | ||
| { | ||
| $this->offset = $offset; | ||
|
|
||
| return $this; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| <?php | ||
|
|
||
| /* | ||
| * This file has been created by developers from BitBag. | ||
| * Feel free to contact us once you face any issues or want to start | ||
| * You can find more information about us on https://bitbag.io and write us | ||
| * an email on hello@bitbag.io. | ||
| */ | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace BitBag\CodingStandard\Twigcs\Dto; | ||
|
|
||
| final class OffsetDto | ||
| { | ||
| /** @var int */ | ||
| private $line = 0; | ||
|
|
||
| /** @var int */ | ||
| private $column = 0; | ||
|
|
||
| public function getLine(): int | ||
| { | ||
| return $this->line; | ||
| } | ||
|
|
||
| public function setLine(int $line): self | ||
| { | ||
| $this->line = $line; | ||
|
|
||
| return $this; | ||
| } | ||
|
|
||
| public function getColumn(): int | ||
| { | ||
| return $this->column; | ||
| } | ||
|
|
||
| public function setColumn(int $column): self | ||
| { | ||
| $this->column = $column; | ||
|
|
||
| return $this; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| <?php | ||
|
|
||
| /* | ||
| * This file has been created by developers from BitBag. | ||
| * Feel free to contact us once you face any issues or want to start | ||
| * You can find more information about us on https://bitbag.io and write us | ||
| * an email on hello@bitbag.io. | ||
| */ | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace BitBag\CodingStandard\Twigcs\Rule; | ||
|
|
||
| use BitBag\CodingStandard\Twigcs\Ruleset\Ruleset; | ||
| use BitBag\CodingStandard\Twigcs\Util\HtmlUtil; | ||
| use FriendsOfTwig\Twigcs\Rule\AbstractRule; | ||
| use FriendsOfTwig\Twigcs\Rule\RuleInterface; | ||
| use FriendsOfTwig\Twigcs\TwigPort\TokenStream; | ||
|
|
||
| final class EmptyLinesRule extends AbstractRule implements RuleInterface | ||
| { | ||
| /** @var string */ | ||
| private $pattern = '#(?<offset>\n{3,})#s'; | ||
|
|
||
| /** @var HtmlUtil */ | ||
| private $htmlUtil; | ||
|
|
||
| /** @var int */ | ||
| private $lineNumberOffset = 2; | ||
|
|
||
| public function __construct($severity, HtmlUtil $htmlUtil) | ||
| { | ||
| parent::__construct($severity); | ||
|
|
||
| $this->htmlUtil = $htmlUtil; | ||
| } | ||
|
|
||
| public function check(TokenStream $tokens) | ||
| { | ||
| $violations = []; | ||
|
|
||
| $content = str_replace("\r", '', $tokens->getSourceContext()->getCode()); | ||
| $this->htmlUtil->stripUnnecessaryTagsAndSavePositions($content); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential SRP break |
||
|
|
||
| foreach ($this->getMultiLines($content) as $multiline) { | ||
| if ($this->htmlUtil->isInsideUnnecessaryTag($multiline['offset'][1])) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the |
||
| continue; | ||
| } | ||
|
|
||
| $offset = $this->htmlUtil->getTwigcsOffset($content, $multiline['offset'][1] + $this->lineNumberOffset); | ||
|
|
||
| $violations[] = $this->createViolation( | ||
| $tokens->getSourceContext()->getPath(), | ||
| $offset->getLine(), | ||
| 0, | ||
| Ruleset::ERROR_MULTIPLE_EMPTY_LINES | ||
| ); | ||
| } | ||
|
|
||
| return $violations; | ||
| } | ||
|
|
||
| private function getMultiLines(string $content): array | ||
| { | ||
| return preg_match_all($this->pattern, $content, $multilines, HtmlUtil::REGEX_FLAGS) | ||
| ? $multilines | ||
| : []; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| <?php | ||
|
|
||
| /* | ||
| * This file has been created by developers from BitBag. | ||
| * Feel free to contact us once you face any issues or want to start | ||
| * You can find more information about us on https://bitbag.io and write us | ||
| * an email on hello@bitbag.io. | ||
| */ | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace BitBag\CodingStandard\Twigcs\Rule\Html; | ||
|
|
||
| use BitBag\CodingStandard\Twigcs\Ruleset\Ruleset; | ||
| use BitBag\CodingStandard\Twigcs\Util\HtmlUtil; | ||
| use FriendsOfTwig\Twigcs\Rule\AbstractRule; | ||
| use FriendsOfTwig\Twigcs\Rule\RuleInterface; | ||
| use FriendsOfTwig\Twigcs\TwigPort\TokenStream; | ||
|
|
||
| final class ApostropheInAttributesRule extends AbstractRule implements RuleInterface | ||
| { | ||
| /** @var string */ | ||
| private $pattern = "#=\s*(?<offset>')#"; | ||
|
|
||
| /** @var HtmlUtil */ | ||
| private $htmlUtil; | ||
|
|
||
| public function __construct($severity, HtmlUtil $htmlUtil) | ||
| { | ||
| parent::__construct($severity); | ||
|
|
||
| $this->htmlUtil = $htmlUtil; | ||
| } | ||
|
|
||
| public function check(TokenStream $tokens) | ||
| { | ||
| $violations = []; | ||
| $content = $this->htmlUtil->stripUnnecessaryTagsAndSavePositions($tokens->getSourceContext()->getCode()); | ||
|
|
||
| foreach ($this->htmlUtil->getParsedHtmlTags($content) as $tag) { | ||
| foreach ($this->getApostrophes($tag->getHtml()) as $apostrophe) { | ||
| $offset = $this->htmlUtil->getTwigcsOffset($content, $tag->getOffset() + $apostrophe['offset'][1]); | ||
|
|
||
| $violations[] = $this->createViolation( | ||
| $tokens->getSourceContext()->getPath(), | ||
| $offset->getLine(), | ||
| $offset->getColumn(), | ||
| sprintf(Ruleset::ERROR_APOSTROPHE_IN_ATTRIBUTE, $tag->getTag()) | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| return $violations; | ||
| } | ||
|
|
||
| private function getApostrophes(string $html): array | ||
| { | ||
| return preg_match_all($this->pattern, $html, $quotes, HtmlUtil::REGEX_FLAGS) | ||
| ? $quotes | ||
| : []; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| <?php | ||
|
|
||
| /* | ||
| * This file has been created by developers from BitBag. | ||
| * Feel free to contact us once you face any issues or want to start | ||
| * You can find more information about us on https://bitbag.io and write us | ||
| * an email on hello@bitbag.io. | ||
| */ | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace BitBag\CodingStandard\Twigcs\Rule\Html; | ||
|
|
||
| use BitBag\CodingStandard\Twigcs\Ruleset\Ruleset; | ||
| use BitBag\CodingStandard\Twigcs\Util\HtmlUtil; | ||
| use FriendsOfTwig\Twigcs\Rule\AbstractRule; | ||
| use FriendsOfTwig\Twigcs\Rule\RuleInterface; | ||
| use FriendsOfTwig\Twigcs\TwigPort\TokenStream; | ||
|
|
||
| final class MultiWhitespaceInAttributesRule extends AbstractRule implements RuleInterface | ||
| { | ||
| /** @var string */ | ||
| private $pattern = '#(?<offset>\s{2,})#'; | ||
|
|
||
| /** @var HtmlUtil */ | ||
| private $htmlUtil; | ||
|
|
||
| public function __construct($severity, HtmlUtil $htmlUtil) | ||
| { | ||
| parent::__construct($severity); | ||
|
|
||
| $this->htmlUtil = $htmlUtil; | ||
| } | ||
|
|
||
| public function check(TokenStream $tokens) | ||
|
||
| { | ||
| $violations = []; | ||
| $content = $this->htmlUtil->stripUnnecessaryTagsAndSavePositions($tokens->getSourceContext()->getCode()); | ||
|
|
||
| foreach ($this->htmlUtil->getParsedHtmlTags($content) as $tag) { | ||
| foreach ($this->getMultiSpaces($tag->getHtml()) as $space) { | ||
| $offset = $this->htmlUtil->getTwigcsOffset($content, $tag->getOffset() + $space['offset'][1]); | ||
|
|
||
| $violations[] = $this->createViolation( | ||
| $tokens->getSourceContext()->getPath(), | ||
| $offset->getLine(), | ||
| $offset->getColumn(), | ||
| sprintf(Ruleset::ERROR_MULTIPLE_WHITESPACES, $tag->getTag()) | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| return $violations; | ||
| } | ||
|
|
||
| private function getMultiSpaces(string $html): array | ||
| { | ||
| return preg_match_all($this->pattern, $html, $spaces, HtmlUtil::REGEX_FLAGS) | ||
| ? $spaces | ||
| : []; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the "and" in method tells us, it's not SRP friendly ;)