Passed
Push — master ( ad0973...f9c297 )
by Kacper
02:48
created

Php::getRules()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 89
Code Lines 59

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 89
rs 8.5731
cc 1
eloc 59
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) 2015, 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\RegexMatcher;
19
use Kadet\Highlighter\Matcher\SubStringMatcher;
20
use Kadet\Highlighter\Matcher\WordMatcher;
21
use Kadet\Highlighter\Parser\CloseRule;
22
use Kadet\Highlighter\Parser\Token\LanguageToken;
23
use Kadet\Highlighter\Parser\Token\ContextualToken;
24
use Kadet\Highlighter\Parser\Rule;
25
use Kadet\Highlighter\Parser\OpenRule;
26
use Kadet\Highlighter\Parser\Token\Token;
27
use Kadet\Highlighter\Parser\TokenFactory;
28
29
class Php extends Language
30
{
31
    /**
32
     * Tokenization rules
33
     *
34
     * @return \Kadet\Highlighter\Parser\Rule[]|\Kadet\Highlighter\Parser\Rule[][]
35
     */
36
    public function setupRules()
37
    {
38
        $this->rules->addMany([
39
            'string.single' => new Rule(new SubStringMatcher('\''), [
40
                'context' => ['!keyword.escape', '!comment', '!string', '!keyword.nowdoc'],
41
                'factory' => new TokenFactory(ContextualToken::class),
42
            ]),
43
44
            'string.double' => new Rule(new SubStringMatcher('"'), [
45
                'context' => ['!keyword.escape', '!comment', '!string'],
46
                'factory' => new TokenFactory(ContextualToken::class),
47
            ]),
48
49
            'string.heredoc' => new Rule(new RegexMatcher('/<<<\s*(\w+)(?P<string>.*?)\n\1;/sm', ['string' => Token::NAME, 0 => 'keyword.heredoc']), ['context' => ['!comment']]),
50
            'string.nowdoc'  => new Rule(new RegexMatcher('/<<<\s*\'(\w+)\'(?P<string>.*?)\n\1;/sm', ['string' => Token::NAME, 0 => 'keyword.nowdoc']), ['context' => ['!comment']]),
51
52
            'variable' => new Rule(new RegexMatcher('/[^\\\](\$[a-z_]\w*)/i'), [
53
                'context' => ['*comment.docblock', '!string.nowdoc', '!string.single', '!comment']
54
            ]),
55
            'variable.property' => new Rule(new RegexMatcher('/(?=(?:\w|\)|\])\s*->([a-z_]\w*))/i'), [
56
                'priority' => -2
57
            ]),
58
59
            'symbol.function' => new Rule(new RegexMatcher('/function\s+([a-z_]\w+)\s*\(/i')),
60
            'symbol.class'    => [
61
                new Rule(new RegexMatcher('/(?:class|new|use|extends)\s+([\w\\\]+)/i')),
62
                new Rule(new RegexMatcher('/([\w\\\]+)::/i')),
63
                new Rule(new RegexMatcher('/@(?:var|property(?:-read|-write)?)\s+([^\$][\w\\\]+)/i'), ['context' => ['comment.docblock']]),
64
            ],
65
66
            'symbol.class.interface' => [
67
                new Rule(new RegexMatcher('/interface\s+([\w\\\]+)/i')),
68
                new Rule(new RegexMatcher('/implements\s+([\w\\\]+)(?:,\s*([\w\\\]+))*/i'), [
69
                    1 => Token::NAME,
70
                    2 => Token::NAME
71
                ]),
72
            ],
73
74
            'symbol.namespace' => new Rule(new RegexMatcher('/(\\\{0,2}(?:\w+\\\{1,2})+\w+)/i'), [
75
                'context' => ['*symbol', '*none']
76
            ]),
77
78
            'keyword.escape' => new Rule(new RegexMatcher('/(\\\(?:x[0-9a-fA-F]{1,2}|u\{[0-9a-fA-F]{1,6}\}|[0-7]{1,3}|.))/i'), [
79
                'context' => ['string']
80
            ]),
81
82
            'comment' => new Rule(new CommentMatcher(['//', '#'], [
83
                '$.docblock' => ['/**', '*/'],
84
                ['/* ', '*/']
85
            ])),
86
87
            'keyword.annotation' => new Rule(new RegexMatcher('/[\s]+(@[\w-]+)/i'), [
88
                'context' => ['comment.docblock']
89
            ]),
90
91
            'call' => new Rule(new RegexMatcher('/([a-z_]\w*)\s*\(/i'), ['priority' => -1]),
92
93
            'constant' => new Rule(new WordMatcher(array_merge([
94
                '__CLASS__', '__DIR__', '__FILE__', '__FUNCTION__',
95
                '__LINE__', '__METHOD__', '__NAMESPACE__', '__TRAIT__',
96
            ], array_keys(get_defined_constants(true)["Core"]))), ['priority' => -2]),
97
            'constant.static' => new Rule(new RegexMatcher('/(?:[\w\\\]+::|const\s+)(\w+)/i'), ['priority' => -2]),
98
99
            'keyword' => new Rule(new WordMatcher([
100
                '__halt_compiler', 'abstract', 'and', 'array',
101
                'as', 'break', 'callable', 'case', 'catch',
102
                'class', 'clone', 'const', 'continue', 'declare',
103
                'default', 'die', 'do', 'echo', 'else', 'elseif',
104
                'empty', 'enddeclare', 'endfor', 'endforeach', 'endif',
105
                'endswitch', 'endwhile', 'eval', 'exit', 'extends',
106
                'final', 'finally', 'for', 'foreach', 'function',
107
                'global', 'goto', 'if', 'implements', 'include', 'include_once',
108
                'instanceof', 'insteadof', 'interface', 'isset', 'list',
109
                'namespace', 'new', 'or', 'print', 'private', 'protected',
110
                'public', 'require', 'require_once', 'return', 'static',
111
                'switch', 'throw', 'trait', 'try', 'unset', 'parent', 'self',
112
                'use', 'var', 'while', 'xor', 'yield'
113
            ]), ['context' => ['!string', '!variable', '!comment']]),
114
115
            'keyword.cast' => new Rule(
116
                new RegexMatcher('/(\((?:int|integer|bool|boolean|float|double|real|string|array|object|unset)\))/')
117
            ),
118
119
            'delimiter' => new Rule(new RegexMatcher('/(<\?php|<\?=|\?>)/')),
120
            'number'    => new Rule(new RegexMatcher('/(-?(?:0[0-7]+|0[xX][0-9a-fA-F]+|0b[01]+|\d+))/')),
121
122
            'operator.punctuation' => new Rule(new WordMatcher([',', ';'], ['separated' => false]), ['priority' => 0]),
123
        ]);
124
    }
125
126
    /** {@inheritdoc} */
127
    public function getEnds($embedded = false)
128
    {
129
        return $embedded ? [
1 ignored issue
show
Bug Compatibility introduced by
The expression $embedded ? array(new \K...parent::getEnds(false); of type array<Kadet\Highlighter\...Highlighter\Parser\Rule adds the type array<Kadet\Highlighter\...ghter\Parser\CloseRule> to the return on line 129 which is incompatible with the return type of the parent method Kadet\Highlighter\Language\Language::getEnds of type Kadet\Highlighter\Parser\Rule.
Loading history...
130
            new OpenRule(new RegexMatcher('/(<\?php|<\?=)/si'), [
131
                'factory'  => new TokenFactory(LanguageToken::class),
132
                'priority' => 1000,
133
                'context'  => ['*'],
134
                'inject'   => $this,
135
                'language' => null
136
            ]),
137
            new CloseRule(new RegexMatcher('/(\?>|$)/'), [
138
                'context'  => ['!string', '!comment'],
139
                'priority' => 1000,
140
                'factory'  => new TokenFactory(LanguageToken::class),
141
                'language' => $this
142
            ])
143
        ] : parent::getEnds(false);
144
    }
145
146
    public function getIdentifier()
147
    {
148
        return 'php';
149
    }
150
}
151