Completed
Push — master ( da54d7...33d164 )
by Colin
25s queued 10s
created

AdjacentTextMerger   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 97.5%

Importance

Changes 0
Metric Value
dl 0
loc 69
c 0
b 0
f 0
wmc 16
lcom 1
cbo 2
ccs 39
cts 40
cp 0.975
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A mergeChildNodes() 0 9 2
A mergeTextNodesBetweenExclusive() 0 9 3
A mergeTextNodesInclusive() 0 25 5
B mergeIfNeeded() 0 20 6
1
<?php
2
3
/*
4
 * This file is part of the league/commonmark package.
5
 *
6
 * (c) Colin O'Dell <[email protected]>
7
 *
8
 * Additional emphasis processing code based on commonmark-java (https://github.com/atlassian/commonmark-java)
9
 *  - (c) Atlassian Pty Ltd
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace League\CommonMark\Inline;
16
17
use League\CommonMark\Inline\Element\Text;
18
use League\CommonMark\Node\Node;
19
20
/**
21
 * @internal
22
 */
23
final class AdjacentTextMerger
24
{
25 1746
    public static function mergeChildNodes(Node $node)
26
    {
27
        // No children or just one child node, no need for merging
28 1746
        if ($node->firstChild() === $node->lastChild()) {
29 1125
            return;
30
        }
31
32 801
        self::mergeTextNodesInclusive($node->firstChild(), $node->lastChild());
0 ignored issues
show
Bug introduced by
It seems like $node->firstChild() can be null; however, mergeTextNodesInclusive() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
Bug introduced by
It seems like $node->lastChild() can be null; however, mergeTextNodesInclusive() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
33 801
    }
34
35 354
    public static function mergeTextNodesBetweenExclusive(Node $fromNode, Node $toNode)
36
    {
37
        // No nodes between them
38 354
        if ($fromNode === $toNode || $fromNode->next() === $toNode) {
39
            return;
40
        }
41
42 354
        self::mergeTextNodesInclusive($fromNode->next(), $toNode->previous());
0 ignored issues
show
Bug introduced by
It seems like $fromNode->next() can be null; however, mergeTextNodesInclusive() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
Bug introduced by
It seems like $toNode->previous() can be null; however, mergeTextNodesInclusive() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
43 354
    }
44
45 981
    private static function mergeTextNodesInclusive(Node $fromNode, Node $toNode)
46
    {
47 981
        $first = null;
48 981
        $last = null;
49
50 981
        $node = $fromNode;
51 981
        while ($node !== null) {
52 981
            if ($node instanceof Text) {
53 960
                if ($first === null) {
54 960
                    $first = $node;
55
                }
56 960
                $last = $node;
57
            } else {
58 678
                self::mergeIfNeeded($first, $last);
59 678
                $first = null;
60 678
                $last = null;
61
            }
62 981
            if ($node === $toNode) {
63 981
                break;
64
            }
65 924
            $node = $node->next();
66
        }
67
68 981
        self::mergeIfNeeded($first, $last);
69 981
    }
70
71 981
    private static function mergeIfNeeded(?Text $first, ?Text $last)
72
    {
73 981
        if ($first === null || $last === null || $first === $last) {
74
            // No merging needed
75 708
            return;
76
        }
77
78 420
        $s = $first->getContent();
79
80 420
        $node = $first->next();
81 420
        $stop = $last->next();
82 420
        while ($node !== $stop && $node instanceof Text) {
83 420
            $s .= $node->getContent();
84 420
            $unlink = $node;
85 420
            $node = $node->next();
86 420
            $unlink->detach();
87
        }
88
89 420
        $first->setContent($s);
90 420
    }
91
}
92