Passed
Push — master ( eb8fe1...f9b36a )
by Maxim
03:07
created

CommentLexer   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 0
loc 90
ccs 0
cts 24
cp 0
rs 10
c 0
b 0
f 0
wmc 7

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getAxsComment() 0 3 1
A getClassData() 0 21 4
A isAxsPropertyDef() 0 4 1
A getPropertyName() 0 4 1
1
<?php
2
/**
3
 * This file is a part of "Axessors" library.
4
 *
5
 * @author <[email protected]>
6
 * @license GPL
7
 */
8
9
namespace NoOne4rever\Axessors;
10
11
/**
12
 * Class CommentLexer.
13
 *
14
 * Splits Axessors comment into array of possible tokens.
15
 * 
16
 * @package NoOne4rever\Axessors
17
 */
18
class CommentLexer extends Lexer
19
{
20
    private const AXS_COMMENT = '{^#>}';
21
    private const ACCESS_MODIFIER = '{^(\+|~|-)}';
22
    private const KEYWORD = '{^((accessi|(writ|read)a)ble|axs|wrt|rdb)}';
23
    private const TYPE = '{^((((\\\\)?[a-zA-Z_][a-zA-Z\d_]*(\\\\[a-zA-Z_][a-zA-Z\d_]*)*)(\[(?1)\])?)(\|(?2))*)}';
24
    private const HANDLERS = '{^((?(1),\s*)([a-zA-Z_][a-zA-Z0-9_]*|`([^`]|\\\\`)+((?<!\\\\)`)))+}';
25
    private const CONDITIONS = '{^((?(1)\s*(&&|\|\|)\s*)(\d+(,\d+)?\.\.\d+(,\d+)?|((<|>|!|=)=|%|<|>)\s+\d+(,\d+)?|`([^`]|\\\\`)+((?<!\\\\)`)))+}';
26
    private const HANDLERS_SIGN = '{^>>}';
27
    private const ALIAS_SIGN = '{^=>}';
28
    private const ALIAS = '{^[a-zA-Z_][a-zA-Z0-9_]*}';
29
30
    private const TOKEN_LIST = [
31
        self::AXS_COMMENT,
32
        self::ACCESS_MODIFIER,
33
        self::KEYWORD,
34
        self::TYPE,
35
        self::CONDITIONS,
36
        self::HANDLERS_SIGN,
37
        self::HANDLERS,
38
        self::ACCESS_MODIFIER,
39
        self::KEYWORD,
40
        self::CONDITIONS,
41
        self::HANDLERS_SIGN,
42
        self::HANDLERS,
43
        self::ALIAS_SIGN,
44
        self::ALIAS
45
    ];
46
    private const REQUIRED_TOKENS = [0, 1, 2];
47
48
    private const AXS_COMMENT_TOKEN = '#>';
49
50
    /**
51
     * Returns class' data with Axessors properties.
52
     * 
53
     * @return ClassData class' data
54
     */
55
    public function getClassData(): ClassData
56
    {
57
        $classData = new ClassData($this->reflection);
58
        for ($i = $this->startLine; $this->isLineEmpty() && $i <= $this->endLine; ++$i) {
59
            $this->readLine();
60
            if (!$this->isAxsPropertyDef()) {
61
                continue;
62
            }
63
            $injProcessor = new InjectedStringParser($this->getAxsComment());
64
            $code = $injProcessor->addSlashes('\\');
65
            $propertyData = new PropertyData(
66
                $this->reflection->getProperty($this->getPropertyName()),
67
                $this->parse(
68
                    $code,
69
                    self::TOKEN_LIST,
70
                    self::REQUIRED_TOKENS
71
                )
72
            );
73
            $classData->addProperty($this->getPropertyName(), $propertyData);
74
        }
75
        return $classData;
76
    }
77
78
    /**
79
     * Extracts Axessors comment from the code.
80
     * 
81
     * @return string Axessors comment
82
     */
83
    private function getAxsComment(): string
84
    {
85
        return substr($this->currentLine, strpos($this->currentLine, self::AXS_COMMENT_TOKEN));
86
    }
87
88
    /**
89
     * Extracts property name from the code.
90
     * 
91
     * @return string property name
92
     */
93
    private function getPropertyName(): string
94
    {
95
        preg_match('{\$[a-zA-Z_][a-zA-Z0-9_]*}', $this->currentLine, $property);
96
        return substr($property[0], 1);
97
    }
98
99
    /**
100
     * Checks if the code given is Axessors property definition. 
101
     * 
102
     * @return bool result of the checkout
103
     */
104
    private function isAxsPropertyDef(): bool
105
    {
106
        return (bool)preg_match('{^\s*(public|private|protected)\s+(static\s+)?\$[a-zA-Z_][a-zA-Z0-9_]*.*?;\s+#>}',
107
            $this->currentLine);
108
    }
109
}
110