GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 15e8d5...9ebb39 )
by Colin
04:59
created

Environment   C

↳ Parent: Project

Coupling/Cohesion

Components 1
Dependencies 7

Complexity

Total Complexity 57

Size/Duplication

Total Lines 504
Duplicated Lines 0 %

Test Coverage

Coverage 94.44%

Importance

Changes 7
Bugs 1 Features 2
Metric Value
wmc 57
c 7
b 1
f 2
lcom 1
cbo 7
dl 0
loc 504
ccs 170
cts 180
cp 0.9444
rs 6.4331

34 Methods

Rating   Name   Duplication   Size   Complexity  
A mergeConfig() 0 6 1
A getConfig() 0 4 1
A addBlockParser() 0 8 1
A getExtensions() 0 4 1
A addExtension() 0 8 1
A initializeExtensions() 0 18 3
A initalizeBlockParsers() 0 14 4
A createCommonMarkEnvironment() 0 15 1
A getInlineParserCharacterRegex() 0 4 1
A buildInlineParserCharacterRegex() 0 6 1
A assertUninitialized() 0 6 2
A getMiscExtension() 0 12 3
A __construct() 0 4 1
A addInlineParser() 0 8 1
A addInlineProcessor() 0 8 1
A addDocumentProcessor() 0 8 1
A addBlockRenderer() 0 8 1
A addInlineRenderer() 0 8 1
A getBlockParsers() 0 6 1
A getInlineParser() 0 6 1
A getInlineParsers() 0 6 1
A getInlineParsersForCharacter() 0 10 2
A getInlineProcessors() 0 6 1
A getDocumentProcessors() 0 6 1
A getBlockRendererForClass() 0 10 2
A getInlineRendererForClass() 0 10 2
A createInlineParserEngine() 0 6 1
A initializeExtension() 0 9 1
B initializeInlineParsers() 0 18 5
A initializeInlineProcessors() 0 10 3
A initializeDocumentProcessors() 0 10 3
A initializeBlockRenderers() 0 10 3
A initializeInlineRenderers() 0 10 3
A setConfig() 0 6 1

How to fix   Complexity   

Complex Class

Complex classes like Environment often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Environment, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * This file is part of the league/commonmark package.
5
 *
6
 * (c) Colin O'Dell <[email protected]>
7
 *
8
 * Original code based on the CommonMark JS reference parser (http://bitly.com/commonmark-js)
9
 *  - (c) John MacFarlane
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace League\CommonMark;
16
17
use League\CommonMark\Block\Parser\BlockParserInterface;
18
use League\CommonMark\Block\Renderer\BlockRendererInterface;
19
use League\CommonMark\Extension\CommonMarkCoreExtension;
20
use League\CommonMark\Extension\ExtensionInterface;
21
use League\CommonMark\Extension\MiscExtension;
22
use League\CommonMark\Inline\Parser\InlineParserInterface;
23
use League\CommonMark\Inline\Processor\InlineProcessorInterface;
24
use League\CommonMark\Inline\Renderer\InlineRendererInterface;
25
use League\CommonMark\Util\Configuration;
26
use League\CommonMark\Util\ConfigurationAwareInterface;
27
28
class Environment
29
{
30
    /**
31
     * @var ExtensionInterface[]
32
     */
33
    protected $extensions = [];
34
35
    /**
36
     * @var bool
37
     */
38
    protected $extensionsInitialized = false;
39
40
    /**
41
     * @var BlockParserInterface[]
42
     */
43
    protected $blockParsers = [];
44
45
    /**
46
     * @var InlineParserInterface[]
47
     */
48
    protected $inlineParsers = [];
49
50
    /**
51
     * @var array
52
     */
53
    protected $inlineParsersByCharacter = [];
54
55
    /**
56
     * @var DocumentProcessorInterface[]
57
     */
58
    protected $documentProcessors = [];
59
60
    /**
61
     * @var InlineProcessorInterface[]
62
     */
63
    protected $inlineProcessors = [];
64
65
    /**
66
     * @var BlockRendererInterface[]
67
     */
68
    protected $blockRenderersByClass = [];
69
70
    /**
71
     * @var InlineRendererInterface[]
72
     */
73
    protected $inlineRenderersByClass = [];
74
75
    /**
76
     * @var Configuration
77
     */
78
    protected $config;
79
80
    /**
81
     * @var string
82
     */
83
    protected $inlineParserCharacterRegex;
84
85 1962
    public function __construct(array $config = [])
86 3
    {
87 1962
        $this->config = new Configuration($config);
88 1962
    }
89
90
    /**
91
     * @param array $config
92
     */
93 1878
    public function mergeConfig(array $config = [])
94
    {
95 1878
        $this->assertUninitialized('Failed to modify configuration - extensions have already been initialized');
96
97 1875
        $this->config->mergeConfig($config);
98 1875
    }
99
100
    /**
101
     * @param array $config
102
     */
103 9
    public function setConfig(array $config = [])
104 3
    {
105 9
        $this->assertUninitialized('Failed to modify configuration - extensions have already been initialized');
106
107 3
        $this->config->setConfig($config);
108 3
    }
109
110
    /**
111
     * @param string|null $key
112
     * @param mixed       $default
113
     *
114
     * @return mixed
115
     */
116 1884
    public function getConfig($key = null, $default = null)
117
    {
118 1884
        return $this->config->getConfig($key, $default);
119
    }
120
121
    /**
122
     * @param BlockParserInterface $parser
123
     *
124
     * @return $this
125
     */
126 6
    public function addBlockParser(BlockParserInterface $parser)
127
    {
128 6
        $this->assertUninitialized('Failed to add block parser - extensions have already been initialized');
129
130 3
        $this->getMiscExtension()->addBlockParser($parser);
131
132 3
        return $this;
133
    }
134
135
    /**
136
     * @param InlineParserInterface $parser
137
     *
138
     * @return $this
139
     */
140 15
    public function addInlineParser(InlineParserInterface $parser)
141
    {
142 15
        $this->assertUninitialized('Failed to add inline parser - extensions have already been initialized');
143
144 12
        $this->getMiscExtension()->addInlineParser($parser);
145
146 12
        return $this;
147
    }
148
149
    /**
150
     * @param InlineProcessorInterface $processor
151
     *
152
     * @return $this
153
     */
154 6
    public function addInlineProcessor(InlineProcessorInterface $processor)
155
    {
156 6
        $this->assertUninitialized('Failed to add inline processor - extensions have already been initialized');
157
158 3
        $this->getMiscExtension()->addInlineProcessor($processor);
159
160 3
        return $this;
161
    }
162
163
    /**
164
     * @param DocumentProcessorInterface $processor
165
     *
166
     * @return $this
167
     */
168 9
    public function addDocumentProcessor(DocumentProcessorInterface $processor)
169
    {
170 9
        $this->assertUninitialized('Failed to add document processor - extensions have already been initialized');
171
172 6
        $this->getMiscExtension()->addDocumentProcessor($processor);
173
174 6
        return $this;
175
    }
176
177
    /**
178
     * @param string                 $blockClass
179
     * @param BlockRendererInterface $blockRenderer
180
     *
181
     * @return $this
182
     */
183 9
    public function addBlockRenderer($blockClass, BlockRendererInterface $blockRenderer)
184
    {
185 9
        $this->assertUninitialized('Failed to add block renderer - extensions have already been initialized');
186
187 6
        $this->getMiscExtension()->addBlockRenderer($blockClass, $blockRenderer);
188
189 6
        return $this;
190
    }
191
192
    /**
193
     * @param string                  $inlineClass
194
     * @param InlineRendererInterface $renderer
195
     *
196
     * @return $this
197
     */
198 9
    public function addInlineRenderer($inlineClass, InlineRendererInterface $renderer)
199
    {
200 9
        $this->assertUninitialized('Failed to add inline renderer - extensions have already been initialized');
201
202 6
        $this->getMiscExtension()->addInlineRenderer($inlineClass, $renderer);
203
204 6
        return $this;
205
    }
206
207
    /**
208
     * @return BlockParserInterface[]
209
     */
210 1884
    public function getBlockParsers()
211
    {
212 1884
        $this->initializeExtensions();
213
214 1884
        return $this->blockParsers;
215
    }
216
217
    /**
218
     * @param string $name
219
     *
220
     * @return InlineParserInterface
221
     */
222 3
    public function getInlineParser($name)
223
    {
224 3
        $this->initializeExtensions();
225
226 3
        return $this->inlineParsers[$name];
227
    }
228
229
    /**
230
     * @return InlineParserInterface[]
231
     */
232 6
    public function getInlineParsers()
233
    {
234 6
        $this->initializeExtensions();
235
236 6
        return $this->inlineParsers;
237
    }
238
239
    /**
240
     * @param string $character
241
     *
242
     * @return InlineParserInterface[]|null
243
     */
244 1605
    public function getInlineParsersForCharacter($character)
245
    {
246 1605
        $this->initializeExtensions();
247
248 1605
        if (!isset($this->inlineParsersByCharacter[$character])) {
249 1503
            return;
250
        }
251
252 1215
        return $this->inlineParsersByCharacter[$character];
253
    }
254
255
    /**
256
     * @return InlineProcessorInterface[]
257
     */
258 1608
    public function getInlineProcessors()
259
    {
260 1608
        $this->initializeExtensions();
261
262 1608
        return $this->inlineProcessors;
263
    }
264
265
    /**
266
     * @return DocumentProcessorInterface[]
267
     */
268 1878
    public function getDocumentProcessors()
269
    {
270 1878
        $this->initializeExtensions();
271
272 1878
        return $this->documentProcessors;
273
    }
274
275
    /**
276
     * @param string $blockClass
277
     *
278
     * @return BlockRendererInterface|null
279
     */
280 1884
    public function getBlockRendererForClass($blockClass)
281
    {
282 1884
        $this->initializeExtensions();
283
284 1884
        if (!isset($this->blockRenderersByClass[$blockClass])) {
285 6
            return;
286
        }
287
288 1878
        return $this->blockRenderersByClass[$blockClass];
289
    }
290
291
    /**
292
     * @param string $inlineClass
293
     *
294
     * @return InlineRendererInterface|null
295
     */
296 1614
    public function getInlineRendererForClass($inlineClass)
297
    {
298 1614
        $this->initializeExtensions();
299
300 1614
        if (!isset($this->inlineRenderersByClass[$inlineClass])) {
301 9
            return;
302
        }
303
304 1605
        return $this->inlineRenderersByClass[$inlineClass];
305
    }
306
307 3
    public function createInlineParserEngine()
308
    {
309 3
        $this->initializeExtensions();
310
311 3
        return new InlineParserEngine($this);
312
    }
313
314
    /**
315
     * Get all registered extensions
316
     *
317
     * @return ExtensionInterface[]
318
     */
319 9
    public function getExtensions()
320
    {
321 9
        return $this->extensions;
322
    }
323
324
    /**
325
     * Add a single extension
326
     *
327
     * @param ExtensionInterface $extension
328
     *
329
     * @return $this
330
     */
331 1914
    public function addExtension(ExtensionInterface $extension)
332
    {
333 1914
        $this->assertUninitialized('Failed to add extension - extensions have already been initialized');
334
335 1911
        $this->extensions[] = $extension;
336
337 1911
        return $this;
338
    }
339
340 1941
    protected function initializeExtensions()
341
    {
342
        // Only initialize them once
343 1941
        if ($this->extensionsInitialized) {
344 1878
            return;
345
        }
346
347 1941
        $this->extensionsInitialized = true;
348
349
        // Initialize all the registered extensions
350 1941
        foreach ($this->extensions as $extension) {
351 1902
            $this->initializeExtension($extension);
352 1941
        }
353
354
        // Lastly, let's build a regex which matches all inline characters
355
        // This will enable a huge performance boost with inline parsing
356 1941
        $this->buildInlineParserCharacterRegex();
357 1941
    }
358
359
    /**
360
     * @param ExtensionInterface $extension
361
     */
362 1902
    protected function initializeExtension(ExtensionInterface $extension)
363
    {
364 1902
        $this->initalizeBlockParsers($extension->getBlockParsers());
365 1902
        $this->initializeInlineParsers($extension->getInlineParsers());
366 1902
        $this->initializeInlineProcessors($extension->getInlineProcessors());
367 1902
        $this->initializeDocumentProcessors($extension->getDocumentProcessors());
368 1902
        $this->initializeBlockRenderers($extension->getBlockRenderers());
369 1902
        $this->initializeInlineRenderers($extension->getInlineRenderers());
370 1902
    }
371
372
    /**
373
     * @param BlockParserInterface[] $blockParsers
374
     */
375 1902
    private function initalizeBlockParsers($blockParsers)
376
    {
377 1902
        foreach ($blockParsers as $blockParser) {
378 1875
            if ($blockParser instanceof EnvironmentAwareInterface) {
379
                $blockParser->setEnvironment($this);
380
            }
381
382 1875
            if ($blockParser instanceof ConfigurationAwareInterface) {
383
                $blockParser->setConfiguration($this->config);
384
            }
385
386 1875
            $this->blockParsers[$blockParser->getName()] = $blockParser;
387 1902
        }
388 1902
    }
389
390
    /**
391
     * @param InlineParserInterface[] $inlineParsers
392
     */
393 1902
    private function initializeInlineParsers($inlineParsers)
394
    {
395 1902
        foreach ($inlineParsers as $inlineParser) {
396 1881
            if ($inlineParser instanceof EnvironmentAwareInterface) {
397 1872
                $inlineParser->setEnvironment($this);
398 1872
            }
399
400 1881
            if ($inlineParser instanceof ConfigurationAwareInterface) {
401
                $inlineParser->setConfiguration($this->config);
402
            }
403
404 1881
            $this->inlineParsers[$inlineParser->getName()] = $inlineParser;
405
406 1881
            foreach ($inlineParser->getCharacters() as $character) {
407 1881
                $this->inlineParsersByCharacter[$character][] = $inlineParser;
408 1881
            }
409 1902
        }
410 1902
    }
411
412
    /**
413
     * @param InlineProcessorInterface[] $inlineProcessors
414
     */
415 1902
    private function initializeInlineProcessors($inlineProcessors)
416
    {
417 1902
        foreach ($inlineProcessors as $inlineProcessor) {
418 1875
            $this->inlineProcessors[] = $inlineProcessor;
419
420 1875
            if ($inlineProcessor instanceof ConfigurationAwareInterface) {
421
                $inlineProcessor->setConfiguration($this->config);
422
            }
423 1902
        }
424 1902
    }
425
426
    /**
427
     * @param DocumentProcessorInterface[] $documentProcessors
428
     */
429 1902
    private function initializeDocumentProcessors($documentProcessors)
430
    {
431 1902
        foreach ($documentProcessors as $documentProcessor) {
432 3
            $this->documentProcessors[] = $documentProcessor;
433
434 3
            if ($documentProcessor instanceof ConfigurationAwareInterface) {
435
                $documentProcessor->setConfiguration($this->config);
436
            }
437 1902
        }
438 1902
    }
439
440
    /**
441
     * @param BlockRendererInterface[] $blockRenderers
442
     */
443 1902
    private function initializeBlockRenderers($blockRenderers)
444
    {
445 1902
        foreach ($blockRenderers as $class => $blockRenderer) {
446 1878
            $this->blockRenderersByClass[$class] = $blockRenderer;
447
448 1878
            if ($blockRenderer instanceof ConfigurationAwareInterface) {
449 1872
                $blockRenderer->setConfiguration($this->config);
450 1872
            }
451 1902
        }
452 1902
    }
453
454
    /**
455
     * @param InlineRendererInterface[] $inlineRenderers
456
     */
457 1902
    private function initializeInlineRenderers($inlineRenderers)
458
    {
459 1902
        foreach ($inlineRenderers as $class => $inlineRenderer) {
460 1878
            $this->inlineRenderersByClass[$class] = $inlineRenderer;
461
462 1878
            if ($inlineRenderer instanceof ConfigurationAwareInterface) {
463 1872
                $inlineRenderer->setConfiguration($this->config);
464 1872
            }
465 1902
        }
466 1902
    }
467
468
    /**
469
     * @return Environment
470
     */
471 1872
    public static function createCommonMarkEnvironment()
472
    {
473 1872
        $environment = new static();
474 1872
        $environment->addExtension(new CommonMarkCoreExtension());
475 1872
        $environment->mergeConfig([
476
            'renderer' => [
477 1872
                'block_separator' => "\n",
478 1872
                'inner_separator' => "\n",
479 1872
                'soft_break'      => "\n",
480 1872
            ],
481 1872
            'safe' => false,
482 1872
        ]);
483
484 1872
        return $environment;
485
    }
486
487
    /**
488
     * Regex which matches any character that an inline parser might be interested in
489
     *
490
     * @return string
491
     */
492 1500
    public function getInlineParserCharacterRegex()
493
    {
494 1500
        return $this->inlineParserCharacterRegex;
495
    }
496
497 1941
    private function buildInlineParserCharacterRegex()
498
    {
499 1941
        $chars = array_keys($this->inlineParsersByCharacter);
500
501 1941
        $this->inlineParserCharacterRegex = '/^[^' . preg_quote(implode('', $chars)) . ']+/u';
502 1941
    }
503
504
    /**
505
     * @param string $message
506
     *
507
     * @throws \RuntimeException
508
     */
509 1944
    private function assertUninitialized($message = 'The environment cannot be modified after initialization')
510
    {
511 1944
        if ($this->extensionsInitialized) {
512 27
            throw new \RuntimeException($message);
513
        }
514 1917
    }
515
516
    /**
517
     * @return MiscExtension
518
     */
519 33
    private function getMiscExtension()
520
    {
521 33
        $lastExtension = end($this->extensions);
522 33
        if ($lastExtension !== false && $lastExtension instanceof MiscExtension) {
523 6
            return $lastExtension;
524
        }
525
526 33
        $miscExtension = new MiscExtension();
527 33
        $this->addExtension($miscExtension);
528
529 33
        return $miscExtension;
530
    }
531
}
532