Completed
Push — master ( 606ca4...edcce7 )
by Kacper
05:58
created

JavaScript   A

Complexity

Total Complexity 3

Size/Duplication

Total Lines 93
Duplicated Lines 8.6 %

Coupling/Cohesion

Components 1
Dependencies 11

Test Coverage

Coverage 90.91%

Importance

Changes 0
Metric Value
dl 8
loc 93
rs 10
c 0
b 0
f 0
ccs 50
cts 55
cp 0.9091
wmc 3
lcom 1
cbo 11

3 Methods

Rating   Name   Duplication   Size   Complexity  
B setupRules() 0 66 1
A getIdentifier() 0 4 1
A getMetadata() 8 8 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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\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\Token\MetaToken;
25
use Kadet\Highlighter\Parser\TokenFactory;
26
use Kadet\Highlighter\Parser\Validator\Validator;
27
28
/**
29
 * Class JavaScriptLanguage
30
 *
31
 * @package Kadet\Highlighter\Language
32
 *
33
 * @property bool $variables
34
 */
35
class JavaScript extends GreedyLanguage
36
{
37
    
38
    protected $_options = [
39
        'variables' => false,
40
    ];
41
42
    const IDENTIFIER = '[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*';
43
44
    /**
45
     * Tokenization rules
46
     */
47 2
    public function setupRules()
48
    {
49
        // we need to allow all the tokens in json
50 2
        $this->rules->validator = new Validator(['*none', '*meta.json', '!comment']);
51
52 2
        $this->rules->addMany([
53 2
            'string' => CommonFeatures::strings(['single' => '\'', 'double' => '"'], [
54 2
                'context' => ['!operator.escape', '!comment', '!string'],
55 2
            ]),
56
57 2
            'symbol.function' => new Rule(new RegexMatcher('/function\s+([a-z_]\w+)\s*\(/i')),
58
59 2
            'operator.escape' => new Rule(new RegexMatcher('/(\\\(?:x[0-9a-fA-F]{1,2}|u\{[0-9a-fA-F]{1,6}\}|[0-7]{1,3}|.))/i'), [
60 2
                'context' => ['string']
61 2
            ]),
62
63 2
            'comment' => new Rule(new CommentMatcher(['//'], [['/*', '*/']]), ['priority' => 3]),
64
65 2
            'call' => new Rule(new RegexMatcher('/(' . self::IDENTIFIER . ')\s*\(/iu'), ['priority' => -1]),
66
67 2
            'keyword' => new Rule(new WordMatcher([
68 2
                'do', 'if', 'in', 'for', 'let', 'new', 'try', 'var', 'case', 'else', 'enum', 'eval',
69 2
                'void', 'with', 'break', 'catch', 'class', 'const', 'super', 'throw',
70 2
                'while', 'yield', 'delete', 'export', 'import', 'public', 'return', 'static', 'switch',
71 2
                'typeof', 'default', 'extends', 'finally', 'package', 'private', 'continue', 'debugger',
72 2
                'function', 'arguments', 'interface', 'protected', 'implements', 'instanceof', 'get', 'set', 'from'
73 2
            ]), ['context' => ['!string', '!comment', '!symbol', '!call']]),
74
75 2
            'constant.special' => new Rule(new WordMatcher(['null', 'true', 'false'])),
76 2
            'variable.special' => new Rule(new SubStringMatcher('this')),
77
78 2
            'number' => new Rule(new RegexMatcher('/\b(-?(?:0[0-7]+|0[xX][0-9a-fA-F]+|0b[01]+|\d+))\b/')),
79
80 2
            'operator.punctuation' => new Rule(new WordMatcher([',', ';'], ['separated' => false]), ['priority' => 0]),
81 2
            'operator'             => new Rule(new RegexMatcher('/(=>|\+{1,2}|-{1,2}|={1,3}|\|{1,2}|&{1,2})/'), ['priority' => 0]),
82
83
            'string.regex' => [
84 2
                new OpenRule(new RegexMatcher('#(?>[\[=(?:+,!]|^|return|=>|&&|\|\|)\s*(/).*?/#m'), [
85 2
                    'context' => ['!comment', '!string']
86 2
                ]),
87 2
                new Rule(new RegexMatcher('#\/.*(/[gimuy]{0,5})#m'), [
88 2
                    'priority' => 1,
89 2
                    'factory'  => new TokenFactory(ContextualToken::class),
90 2
                    'context'  => ['!operator.escape', 'string.regex']
91 2
                ])
92 2
            ],
93
94 2
            'variable' => new Rule(new RegexMatcher('/\b(?<!\.)(' . self::IDENTIFIER . ':?)/iu'), [
95 2
                'priority' => -1,
96 2
                'enabled'  => $this->variables
97 2
            ]),
98
99
            'variable.property' => [
100 2
                new Rule(new RegexMatcher('/(?=[\w)\]]\s*\.([a-z_]\w*))/i'), [
101
                    'priority' => -2
102 2
                ]),
103 2
                new Rule(new RegexMatcher('/(\w+)\s*:/si'), [
104 2
                    'context' => ['meta.json', '!comment', '!string']
105 2
                ]),
106 2
            ],
107
108 2
            'meta.json' => new Rule(new RegexMatcher('/(?<=[=(,])\s*(\{(?>[^{}]|(?1))+\})/m'), [
109 2
                'factory' => new TokenFactory(MetaToken::class)
110 2
            ])
111 2
        ]);
112 2
    }
113
114 2
    public function getIdentifier()
115
    {
116 2
        return 'javascript';
117
    }
118
119 View Code Duplication
    public static function getMetadata()
120
    {
121
        return [
122
            'name'      => ['js', 'jscript', 'javascript'],
123
            'mime'      => ['application/javascript', 'application/x-javascript', 'text/x-javascript', 'text/javascript', 'application/json'],
124
            'extension' => ['*.js', '*.jsx'],
125
        ];
126
    }
127
}
128