Passed
Branch symfony-console (1f7bcb)
by Kacper
03:39
created

Php::setupRules()   B

Complexity

Conditions 2
Paths 1

Size

Total Lines 107
Code Lines 67

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 2 Features 1
Metric Value
c 8
b 2
f 1
dl 0
loc 107
rs 8.2857
cc 2
eloc 67
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Highlighter
4
 *
5
 * Copyright (C) 2016, Some right reserved.
6
 * @author Kacper "Kadet" Donat <[email protected]>
7
 *
8
 * Contact with author:
9
 * Xmpp: [email protected]
10
 * E-mail: [email protected]
11
 *
12
 * From Kadet with love.
13
 */
14
15
namespace Kadet\Highlighter\Language;
16
17
use Kadet\Highlighter\Matcher\CommentMatcher;
18
use Kadet\Highlighter\Matcher\DelegateRegexMatcher;
19
use Kadet\Highlighter\Matcher\RegexMatcher;
20
use Kadet\Highlighter\Matcher\WordMatcher;
21
use Kadet\Highlighter\Parser\CloseRule;
22
use Kadet\Highlighter\Parser\Token\LanguageToken;
23
use Kadet\Highlighter\Parser\Rule;
24
use Kadet\Highlighter\Parser\OpenRule;
25
use Kadet\Highlighter\Parser\Token\Token;
26
use Kadet\Highlighter\Parser\TokenFactory;
27
use Kadet\Highlighter\Parser\TokenFactoryInterface;
28
29
class Php extends GreedyLanguage
30
{
31
    
32
    /**
33
     * Tokenization rules
34
     */
35
    public function setupRules()
36
    {
37
        $this->rules->addMany([
38
            'string' => CommonFeatures::strings(['single' => '\'', 'double' => '"'], [
39
                'context' => ['!operator.escape', '!comment', '!string', '!expression'],
40
            ]),
41
42
            'string.heredoc' => new Rule(new RegexMatcher('/<<<\s*(\w+)(?P<string>.*?)\n\1;/sm', ['string' => Token::NAME, 0 => 'keyword.heredoc']), ['context' => ['!comment']]),
43
            'string.nowdoc'  => new Rule(new RegexMatcher('/<<<\s*\'(\w+)\'(?P<string>.*?)\n\1;/sm', ['string' => Token::NAME, 0 => 'keyword.nowdoc']), ['context' => ['!comment']]),
44
45
            'variable' => new Rule(new RegexMatcher('/(?:[^\\\]|^)(\$[a-z_]\w*)/i'), [
46
                'context' => ['*comment.docblock', '!string.nowdoc', '!string.single', '!comment']
47
            ]),
48
            'variable.property' => new Rule(new RegexMatcher('/(?=(?:\w|\)|\])\s*->([a-z_]\w*))/i'), [
49
                'priority' => -2
50
            ]),
51
52
            'symbol.function' => new Rule(new RegexMatcher('/function\s+([a-z_]\w+)\s*\(/i')),
53
            'symbol.class'    => [
54
                new Rule(new RegexMatcher('/(?:class|new|use|extends)\s+([\w\\\]+)/i')),
55
                new Rule(new RegexMatcher('/([\w\\\]+)::/i')),
56
                new Rule(new RegexMatcher('/@(?:var|property(?:-read|-write)?)(?:\s+|\s+\$\w+\s+)([^$][\w\\\]+)/i'), ['context' => ['comment.docblock']]),
57
            ],
58
            
59
            'expression.in-string' => new Rule(new RegexMatcher('/(?=(\{\$((?>[^${}]+|(?1))+)\}))/x'), [
60
                'context' => ['string'],
61
                'factory' => new TokenFactory(LanguageToken::class),
62
                'inject'  => $this
63
            ]),
64
65
            'symbol.class.interface' => [
66
                new Rule(new RegexMatcher('/interface\s+([\w\\\]+)/i')),
67
                new Rule(new DelegateRegexMatcher(
68
                    '/implements\s+((?:[\w\\\]+)(?:,\s*([\w\\\]+))+)/i',
69
                    function($match, TokenFactoryInterface $factory) {
70
                        foreach (preg_split('/,\s*/', $match[1][0], 0, PREG_SPLIT_OFFSET_CAPTURE) as $interface) {
71
                            yield $factory->create(Token::NAME, [
72
                                'pos' => $match[1][1] + $interface[1],
73
                                'length' => strlen($interface[0])]
74
                            );
75
                        }
76
                    }
77
                )),
78
            ],
79
80
            'symbol.namespace' => [
81
                /*new Rule(new RegexMatcher('/(\\\{0,2}(?:\w+\\\{1,2})+)\w+/i'), [
82
                    'context' => ['*symbol', '*none']
83
                ]),*/
84
85
                new Rule(new RegexMatcher('/namespace\s*(\\\{0,2}(?:\w+\\\{1,2})+\w+);/i'), [
86
                    'context' => ['*symbol', '*none']
87
                ]),
88
            ],
89
90
            'operator.escape' => [
91
                new Rule(new RegexMatcher('/(\\\(?:x[0-9a-fA-F]{1,2}|u\{[0-9a-fA-F]{1,6}\}|[0-7]{1,3}|[^\'\\\]))/i'), [
92
                    'context' => ['string.double']
93
                ]),
94
                new Rule(new RegexMatcher('/(\\\[\'\\\])/i'), [
95
                    'context' => ['string']
96
                ]),
97
            ],
98
99
            'comment' => new Rule(new CommentMatcher(['//', '#'], [
100
                '$.docblock' => ['/**', '*/'],
101
                ['/* ', '*/']
102
            ])),
103
104
            'symbol.annotation' => new Rule(new RegexMatcher('/[\s]+(@[\w-]+)/i'), [
105
                'context' => ['comment.docblock']
106
            ]),
107
108
            'call' => new Rule(new RegexMatcher('/([a-z_]\w*)\s*\(/i'), ['priority' => -1]),
109
110
            'constant' => new Rule(new WordMatcher(array_merge([
111
                '__CLASS__', '__DIR__', '__FILE__', '__FUNCTION__',
112
                '__LINE__', '__METHOD__', '__NAMESPACE__', '__TRAIT__',
113
            ], array_keys(get_defined_constants(true)["Core"]))), ['priority' => -2]),
114
            'constant.static' => new Rule(new RegexMatcher('/(?:[\w\\\]+::|const\s+)(\w+)/i'), ['priority' => -2]),
115
116
            'keyword' => new Rule(new WordMatcher([
117
                '__halt_compiler', 'abstract', 'and', 'array',
118
                'as', 'break', 'callable', 'case', 'catch',
119
                'class', 'clone', 'const', 'continue', 'declare',
120
                'default', 'die', 'do', 'echo', 'else', 'elseif',
121
                'empty', 'enddeclare', 'endfor', 'endforeach', 'endif',
122
                'endswitch', 'endwhile', 'eval', 'exit', 'extends',
123
                'final', 'finally', 'for', 'foreach', 'function',
124
                'global', 'goto', 'if', 'implements', 'include', 'include_once',
125
                'instanceof', 'insteadof', 'interface', 'isset', 'list',
126
                'namespace', 'new', 'or', 'print', 'private', 'protected',
127
                'public', 'require', 'require_once', 'return', 'static',
128
                'switch', 'throw', 'trait', 'try', 'unset', 'parent', 'self',
129
                'use', 'var', 'while', 'xor', 'yield'
130
            ]), ['context' => ['!string', '!variable', '!comment']]),
131
132
            'keyword.cast' => new Rule(
133
                new RegexMatcher('/(\((?:int|integer|bool|boolean|float|double|real|string|array|object|unset)\))/')
134
            ),
135
136
            'delimiter' => new Rule(new RegexMatcher('/(<\?php|<\?=|\?>)/')),
137
            'number'    => new Rule(new RegexMatcher('/(-?(?:0[0-7]+|0[xX][0-9a-fA-F]+|0b[01]+|\d+))/')),
138
139
            'operator.punctuation' => new Rule(new WordMatcher([',', ';'], ['separated' => false]), ['priority' => 0]),
140
        ]);
141
    }
142
143
    /** {@inheritdoc} */
144
    public function getEnds($embedded = false)
145
    {
146
        return $embedded ? [
147
            new OpenRule(new RegexMatcher('/(<\?php|<\?=)/si'), [
148
                'factory'  => new TokenFactory(LanguageToken::class),
149
                'priority' => 1000,
150
                'context'  => ['*'],
151
                'inject'   => $this,
152
                'language' => null
153
            ]),
154
            new CloseRule(new RegexMatcher('/(\?>|$)/'), [
155
                'context'  => ['!string', '!comment'],
156
                'priority' => 1000,
157
                'factory'  => new TokenFactory(LanguageToken::class),
158
                'language' => $this
159
            ])
160
        ] : parent::getEnds(false);
161
    }
162
163
    public function getIdentifier()
164
    {
165
        return 'php';
166
    }
167
168 View Code Duplication
    public static function getAliases()
169
    {
170
        return [
171
            'name'      => ['php'],
172
            'mime'      => ['text/x-php', 'application/x-php'],
173
            'extension' => ['*.php', '*.phtml', '*.inc', '*.php?'],
174
        ];
175
    }
176
}
177