• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JsonMapper / JsonMapper / 14534615220

18 Apr 2025 11:43AM UTC coverage: 95.789% (-3.9%) from 99.729%
14534615220

push

github

web-flow
refactor: raise minimum php level (#197)

* refactor: raise minumum php level

* refactor: remove dead path from json mapper factory

* refactor: remove dead path in json mapper decode json string

* docs: add changelog entry

4 of 45 new or added lines in 4 files covered. (8.89%)

1001 of 1045 relevant lines covered (95.79%)

64.49 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

25.45
/src/Helpers/DocBlockHelper.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace JsonMapper\Helpers;
6

7
use JsonMapper\Parser\Import;
8
use JsonMapper\ValueObjects\AnnotationMap;
9
use JsonMapper\ValueObjects\ArrayInformation;
10
use JsonMapper\ValueObjects\PropertyType;
11

12
class DocBlockHelper
13
{
14
    private const PATTERN = '/@(?P<annotation>[A-Za-z_-]+)[ \t]+(?P<type>\??(?:[\w\[\]\\\\|<>]+(?:,\s*)?)*)[ \t]*\$?(?P<name>[\w\[\]\\\\|]*)/m';
15

16
    public static function parseDocBlockToAnnotationMap(string $docBlock): AnnotationMap
17
    {
18
        // Strip away the start "/**' and ending "*/"
19
        if (strpos($docBlock, '/**') === 0) {
48✔
20
            $docBlock = \substr($docBlock, 3);
36✔
21
        }
22
        if (substr($docBlock, -2) === '*/') {
48✔
23
            $docBlock = \substr($docBlock, 0, -2);
36✔
24
        }
25
        $docBlock = \trim($docBlock);
48✔
26

27
        $var = null;
48✔
28
        $params = [];
48✔
29
        if (\preg_match_all(self::PATTERN, $docBlock, $matches)) {
48✔
30
            for ($x = 0, $max = count($matches[0]); $x < $max; $x++) {
36✔
31
                if ($matches['annotation'][$x] === 'var') {
36✔
32
                    $var = $matches['type'][$x];
24✔
33
                }
34
                if ($matches['annotation'][$x] === 'param') {
36✔
35
                    $params[$matches['name'][$x]] = $matches['type'][$x];
12✔
36
                }
37
            }
38
        }
39

40
        return new AnnotationMap($var ?: null, $params, null);
48✔
41
    }
42

43
    /**
44
     * @param Import[] $imports
45
     * @return PropertyType[]
46
     */
47
    public static function deriveTypesFromDocBlockType(string $docBlockType, \ReflectionClass $class, array $imports): array
48
    {
NEW
49
        $types = [];
×
50

NEW
51
        if (strpos($docBlockType, '?') === 0) {
×
NEW
52
            $docBlockType = \substr($docBlockType, 1);
×
53
        }
54

NEW
55
        $docBlockTypes = \explode('|', $docBlockType);
×
NEW
56
        $docBlockTypes = \array_filter($docBlockTypes, static function (string $docBlockType) {
×
NEW
57
            return $docBlockType !== 'null';
×
58
        });
59

NEW
60
        foreach ($docBlockTypes as $dt) {
×
NEW
61
            $dt = \trim($dt);
×
NEW
62
            $isAnArrayType = self::isArrayType($dt);
×
63

NEW
64
            if (! $isAnArrayType) {
×
NEW
65
                $type = NamespaceHelper::resolveNamespace($dt, $class->getNamespaceName(), $imports);
×
NEW
66
                $types[] = new PropertyType($type, ArrayInformation::notAnArray());
×
NEW
67
                continue;
×
68
            }
69

NEW
70
            $arrayInformation = self::determineArrayInformation($dt);
×
71

NEW
72
            $type = NamespaceHelper::resolveNamespace(
×
73
                $dt,
NEW
74
                $class->getNamespaceName(),
×
75
                $imports
76
            );
77

NEW
78
            $types[] = new PropertyType($type, $arrayInformation);
×
79
        }
80

NEW
81
        return $types;
×
82
    }
83

84
    private static function isArrayType(string $type): bool
85
    {
NEW
86
        return \substr($type, -2) === '[]'
×
NEW
87
            || \strpos($type, 'list<') === 0
×
NEW
88
            || \strpos($type, 'array<') === 0;
×
89
    }
90

91
    private static function determineArrayInformation(string &$type): ArrayInformation
92
    {
NEW
93
        $levels = 0;
×
NEW
94
        while (true) {
×
NEW
95
            if (substr($type, -2) === '[]') {
×
NEW
96
                $levels++;
×
NEW
97
                $type = \substr($type, 0, -2);
×
98

NEW
99
                continue;
×
100
            }
101

NEW
102
            if (strpos($type, 'list<') === 0) {
×
NEW
103
                $levels++;
×
NEW
104
                $type = \substr($type, 5, -1);
×
105

NEW
106
                continue;
×
107
            }
108

NEW
109
            if (strpos($type, 'array<') === 0) {
×
NEW
110
                $levels++;
×
NEW
111
                $offset = 6;
×
NEW
112
                $commaPosition = strpos($type, ',');
×
NEW
113
                if (is_int($commaPosition)) {
×
NEW
114
                    $offset = $commaPosition + 1;
×
115
                }
NEW
116
                $type = \trim(\substr($type, $offset, -1));
×
117

NEW
118
                continue;
×
119
            }
120

NEW
121
            break;
×
122
        }
123

NEW
124
        return $levels === 0 ? ArrayInformation::notAnArray() : ArrayInformation::multiDimension($levels);
×
125
    }
126
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc