summaryrefslogtreecommitdiff
path: root/vendor/sebastian/lines-of-code/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/sebastian/lines-of-code/src')
-rw-r--r--vendor/sebastian/lines-of-code/src/Counter.php91
-rw-r--r--vendor/sebastian/lines-of-code/src/Exception/Exception.php16
-rw-r--r--vendor/sebastian/lines-of-code/src/Exception/IllogicalValuesException.php16
-rw-r--r--vendor/sebastian/lines-of-code/src/Exception/NegativeValueException.php16
-rw-r--r--vendor/sebastian/lines-of-code/src/Exception/RuntimeException.php14
-rw-r--r--vendor/sebastian/lines-of-code/src/LineCountingVisitor.php82
-rw-r--r--vendor/sebastian/lines-of-code/src/LinesOfCode.php98
7 files changed, 333 insertions, 0 deletions
diff --git a/vendor/sebastian/lines-of-code/src/Counter.php b/vendor/sebastian/lines-of-code/src/Counter.php
new file mode 100644
index 000000000..cfe5e20a7
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/src/Counter.php
@@ -0,0 +1,91 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/lines-of-code.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\LinesOfCode;
+
+use function substr_count;
+use PhpParser\Error;
+use PhpParser\Lexer;
+use PhpParser\Node;
+use PhpParser\NodeTraverser;
+use PhpParser\Parser;
+use PhpParser\ParserFactory;
+
+final class Counter
+{
+ /**
+ * @throws RuntimeException
+ */
+ public function countInSourceFile(string $sourceFile): LinesOfCode
+ {
+ return $this->countInSourceString(file_get_contents($sourceFile));
+ }
+
+ /**
+ * @throws RuntimeException
+ */
+ public function countInSourceString(string $source): LinesOfCode
+ {
+ $linesOfCode = substr_count($source, "\n");
+
+ if ($linesOfCode === 0 && !empty($source)) {
+ $linesOfCode = 1;
+ }
+
+ try {
+ $nodes = $this->parser()->parse($source);
+
+ assert($nodes !== null);
+
+ return $this->countInAbstractSyntaxTree($linesOfCode, $nodes);
+
+ // @codeCoverageIgnoreStart
+ } catch (Error $error) {
+ throw new RuntimeException(
+ $error->getMessage(),
+ (int) $error->getCode(),
+ $error
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * @param Node[] $nodes
+ *
+ * @throws RuntimeException
+ */
+ public function countInAbstractSyntaxTree(int $linesOfCode, array $nodes): LinesOfCode
+ {
+ $traverser = new NodeTraverser;
+ $visitor = new LineCountingVisitor($linesOfCode);
+
+ $traverser->addVisitor($visitor);
+
+ try {
+ /* @noinspection UnusedFunctionResultInspection */
+ $traverser->traverse($nodes);
+ // @codeCoverageIgnoreStart
+ } catch (Error $error) {
+ throw new RuntimeException(
+ $error->getMessage(),
+ (int) $error->getCode(),
+ $error
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ return $visitor->result();
+ }
+
+ private function parser(): Parser
+ {
+ return (new ParserFactory)->create(ParserFactory::PREFER_PHP7, new Lexer);
+ }
+}
diff --git a/vendor/sebastian/lines-of-code/src/Exception/Exception.php b/vendor/sebastian/lines-of-code/src/Exception/Exception.php
new file mode 100644
index 000000000..11d543aa7
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/src/Exception/Exception.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/lines-of-code.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\LinesOfCode;
+
+use Throwable;
+
+interface Exception extends Throwable
+{
+}
diff --git a/vendor/sebastian/lines-of-code/src/Exception/IllogicalValuesException.php b/vendor/sebastian/lines-of-code/src/Exception/IllogicalValuesException.php
new file mode 100644
index 000000000..46a5c1b1f
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/src/Exception/IllogicalValuesException.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/lines-of-code.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\LinesOfCode;
+
+use LogicException;
+
+final class IllogicalValuesException extends LogicException implements Exception
+{
+}
diff --git a/vendor/sebastian/lines-of-code/src/Exception/NegativeValueException.php b/vendor/sebastian/lines-of-code/src/Exception/NegativeValueException.php
new file mode 100644
index 000000000..40d27e1f0
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/src/Exception/NegativeValueException.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/lines-of-code.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\LinesOfCode;
+
+use InvalidArgumentException;
+
+final class NegativeValueException extends InvalidArgumentException implements Exception
+{
+}
diff --git a/vendor/sebastian/lines-of-code/src/Exception/RuntimeException.php b/vendor/sebastian/lines-of-code/src/Exception/RuntimeException.php
new file mode 100644
index 000000000..4e6d66d0d
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/src/Exception/RuntimeException.php
@@ -0,0 +1,14 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/lines-of-code.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\LinesOfCode;
+
+final class RuntimeException extends \RuntimeException implements Exception
+{
+}
diff --git a/vendor/sebastian/lines-of-code/src/LineCountingVisitor.php b/vendor/sebastian/lines-of-code/src/LineCountingVisitor.php
new file mode 100644
index 000000000..ff433b2fc
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/src/LineCountingVisitor.php
@@ -0,0 +1,82 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/lines-of-code.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\LinesOfCode;
+
+use function array_merge;
+use function array_unique;
+use function count;
+use PhpParser\Comment;
+use PhpParser\Node;
+use PhpParser\Node\Expr;
+use PhpParser\NodeVisitorAbstract;
+
+final class LineCountingVisitor extends NodeVisitorAbstract
+{
+ /**
+ * @var int
+ */
+ private $linesOfCode;
+
+ /**
+ * @var Comment[]
+ */
+ private $comments = [];
+
+ /**
+ * @var int[]
+ */
+ private $linesWithStatements = [];
+
+ public function __construct(int $linesOfCode)
+ {
+ $this->linesOfCode = $linesOfCode;
+ }
+
+ public function enterNode(Node $node): void
+ {
+ $this->comments = array_merge($this->comments, $node->getComments());
+
+ if (!$node instanceof Expr) {
+ return;
+ }
+
+ $this->linesWithStatements[] = $node->getStartLine();
+ }
+
+ public function result(): LinesOfCode
+ {
+ $commentLinesOfCode = 0;
+
+ foreach ($this->comments() as $comment) {
+ $commentLinesOfCode += ($comment->getEndLine() - $comment->getStartLine() + 1);
+ }
+
+ return new LinesOfCode(
+ $this->linesOfCode,
+ $commentLinesOfCode,
+ $this->linesOfCode - $commentLinesOfCode,
+ count(array_unique($this->linesWithStatements))
+ );
+ }
+
+ /**
+ * @return Comment[]
+ */
+ private function comments(): array
+ {
+ $comments = [];
+
+ foreach ($this->comments as $comment) {
+ $comments[$comment->getStartLine() . '_' . $comment->getStartTokenPos() . '_' . $comment->getEndLine() . '_' . $comment->getEndTokenPos()] = $comment;
+ }
+
+ return $comments;
+ }
+}
diff --git a/vendor/sebastian/lines-of-code/src/LinesOfCode.php b/vendor/sebastian/lines-of-code/src/LinesOfCode.php
new file mode 100644
index 000000000..41829981a
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/src/LinesOfCode.php
@@ -0,0 +1,98 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/lines-of-code.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\LinesOfCode;
+
+/**
+ * @psalm-immutable
+ */
+final class LinesOfCode
+{
+ /**
+ * @var int
+ */
+ private $linesOfCode;
+
+ /**
+ * @var int
+ */
+ private $commentLinesOfCode;
+
+ /**
+ * @var int
+ */
+ private $nonCommentLinesOfCode;
+
+ /**
+ * @var int
+ */
+ private $logicalLinesOfCode;
+
+ /**
+ * @throws IllogicalValuesException
+ * @throws NegativeValueException
+ */
+ public function __construct(int $linesOfCode, int $commentLinesOfCode, int $nonCommentLinesOfCode, int $logicalLinesOfCode)
+ {
+ if ($linesOfCode < 0) {
+ throw new NegativeValueException('$linesOfCode must not be negative');
+ }
+
+ if ($commentLinesOfCode < 0) {
+ throw new NegativeValueException('$commentLinesOfCode must not be negative');
+ }
+
+ if ($nonCommentLinesOfCode < 0) {
+ throw new NegativeValueException('$nonCommentLinesOfCode must not be negative');
+ }
+
+ if ($logicalLinesOfCode < 0) {
+ throw new NegativeValueException('$logicalLinesOfCode must not be negative');
+ }
+
+ if ($linesOfCode - $commentLinesOfCode !== $nonCommentLinesOfCode) {
+ throw new IllogicalValuesException('$linesOfCode !== $commentLinesOfCode + $nonCommentLinesOfCode');
+ }
+
+ $this->linesOfCode = $linesOfCode;
+ $this->commentLinesOfCode = $commentLinesOfCode;
+ $this->nonCommentLinesOfCode = $nonCommentLinesOfCode;
+ $this->logicalLinesOfCode = $logicalLinesOfCode;
+ }
+
+ public function linesOfCode(): int
+ {
+ return $this->linesOfCode;
+ }
+
+ public function commentLinesOfCode(): int
+ {
+ return $this->commentLinesOfCode;
+ }
+
+ public function nonCommentLinesOfCode(): int
+ {
+ return $this->nonCommentLinesOfCode;
+ }
+
+ public function logicalLinesOfCode(): int
+ {
+ return $this->logicalLinesOfCode;
+ }
+
+ public function plus(self $other): self
+ {
+ return new self(
+ $this->linesOfCode() + $other->linesOfCode(),
+ $this->commentLinesOfCode() + $other->commentLinesOfCode(),
+ $this->nonCommentLinesOfCode() + $other->nonCommentLinesOfCode(),
+ $this->logicalLinesOfCode() + $other->logicalLinesOfCode(),
+ );
+ }
+}