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

JavaScript   A

Complexity

Total Complexity 2

Size/Duplication

Total Lines 77
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 5
Bugs 1 Features 0
Metric Value
wmc 2
c 5
b 1
f 0
lcom 1
cbo 9
dl 0
loc 77
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A setupRules() 0 58 1
A getIdentifier() 0 4 1
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\Token\ContextualToken;
22
use Kadet\Highlighter\Parser\OpenRule;
23
use Kadet\Highlighter\Parser\Rule;
24
use Kadet\Highlighter\Parser\TokenFactory;
25
26
/**
27
 * Class JavaScriptLanguage
28
 *
29
 * @package Kadet\Highlighter\Language
30
 *
31
 * @property bool $variables
32
 */
33
class JavaScript extends Language
34
{
35
    protected $_options = [
36
        'variables' => false,
37
    ];
38
39
    const IDENTIFIER = '[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*';
40
41
    /**
42
     * Tokenization rules
43
     *
44
     * @return \Kadet\Highlighter\Parser\Rule[]|\Kadet\Highlighter\Parser\Rule[][]
45
     */
46
    public function setupRules()
47
    {
48
        $this->rules->addMany([
49
            'string.single' => new Rule(new SubStringMatcher('\''), [
50
                'context' => ['!keyword.escape', '!comment', '!string', '!keyword.nowdoc'],
51
                'factory' => new TokenFactory(ContextualToken::class),
52
            ]),
53
54
            'string.double' => new Rule(new SubStringMatcher('"'), [
55
                'context' => ['!keyword.escape', '!comment', '!string'],
56
                'factory' => new TokenFactory(ContextualToken::class),
57
            ]),
58
            'variable.property' => new Rule(new RegexMatcher('/(?=(?:\w|\)|\])\s*\.([a-z_]\w*))/i'), [
59
                'priority' => -2
60
            ]),
61
62
            'symbol.function' => new Rule(new RegexMatcher('/function\s+([a-z_]\w+)\s*\(/i')),
63
64
            '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'), [
65
                'context' => ['string']
66
            ]),
67
68
            'comment' => new Rule(new CommentMatcher(['//'], [
69
                ['/*', '*/']
70
            ]), ['priority' => 3]),
71
72
            'call' => new Rule(new RegexMatcher('/(' . self::IDENTIFIER . ')\s*\(/iu'), ['priority' => -1]),
73
74
            'keyword' => new Rule(new WordMatcher([
75
                'do', 'if', 'in', 'for', 'let', 'new', 'try', 'var', 'case', 'else', 'enum', 'eval', 'false',
76
                'null', 'this', 'true', 'void', 'with', 'break', 'catch', 'class', 'const', 'super', 'throw',
77
                'while', 'yield', 'delete', 'export', 'import', 'public', 'return', 'static', 'switch',
78
                'typeof', 'default', 'extends', 'finally', 'package', 'private', 'continue', 'debugger',
79
                'function', 'arguments', 'interface', 'protected', 'implements', 'instanceof',
80
            ]), ['context' => ['!string', '!comment']]),
81
82
            'number' => new Rule(new RegexMatcher('/\b(-?(?:0[0-7]+|0[xX][0-9a-fA-F]+|0b[01]+|\d+))\b/')),
83
84
            'operator.punctuation' => new Rule(new WordMatcher([',', ';'], ['separated' => false]), ['priority' => 0]),
85
            'operator'             => new Rule(new RegexMatcher('/(\+{1,2}|-{1,2}|={1,3}|\|{1,2}|&{1,2})/'), ['priority' => 0]),
86
87
            'string.regex' => [
88
                new OpenRule(new RegexMatcher('#(?>[\[=(?:+,!]|^|return|=>|&&|\|\|)\s*(/).*?/#m'), [
89
                    'context' => ['!comment']
90
                ]),
91
                new Rule(new RegexMatcher('#\/.*(/[gimuy]{0,5})#m'), [
92
                    'priority' => 1,
93
                    'factory'  => new TokenFactory(ContextualToken::class),
94
                    'context'  => ['!keyword.escape', 'string.regex']
95
                ])
96
            ],
97
98
            'variable' => new Rule(new RegexMatcher('/\b(?<!\.)(' . self::IDENTIFIER . ':?)/iu'), [
99
                'priority' => -1,
100
                'enabled'  => $this->variables
101
            ])
102
        ]);
103
    }
104
105
    public function getIdentifier()
106
    {
107
        return 'javascript';
108
    }
109
}
110