Passed
Push — master ( 7f8b3f...7ac9f0 )
by Observer
01:45
created

EngineAdditions::compile()   B

Complexity

Conditions 8
Paths 128

Size

Total Lines 28
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 17
c 0
b 0
f 0
nc 128
nop 12
dl 0
loc 28
rs 8.2111

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace VoidEngine;
4
5
class EngineAdditions
6
{
7
    /**
8
     * * Компиляция PHP кода
9
     * 
10
     * TODO: дополнить описание
11
     * 
12
     * @param string $savePath - путь для компиляции
13
     * @param string $iconPath - путь до иконки
14
     * @param string $phpCode - код для компиляции без тэгов
15
     * 
16
     * [@param string $productDescription = null] - описание приложения
17
     * [@param string $productName = null]        - название приложения
18
     * [@param string $productVersion = null]     - версия приложения
19
     * [@param string $companyName = null]        - компания-производителя
20
     * [@param string $copyright = null]          - копирайт
21
     * [@param string $callSharpCode = '']        - чистый C# код
22
     * [@param string $declareSharpCode = '']     - C# код с объявлениями классов
23
     * 
24
     * @return array - возвращает список ошибок компиляции
25
     * 
26
     */
27
    public static function compile (string $savePath, string $iconPath, string $phpCode, string $productDescription = null, string $productName = null, string $productVersion = null, string $companyName = null, string $copyright = null, string $callSharpCode = '', string $declareSharpCode = '', WFObject $dictionary = null, WFObject $assemblies = null): array
28
    {
29
        if ($dictionary === null)
30
            $dictionary = new WFObject ('System.Collections.Generic.Dictionary`2[System.String,System.String]', null);
31
32
        if ($assemblies === null)
33
            $assemblies = getNetArray ('System.String', [
34
                // CORE_DIR .'/CefSharp.dll',
35
                CORE_DIR .'/FastColoredTextBox.dll',
36
                CORE_DIR .'/ScintillaNET.dll'
37
            ]);
38
39
        if ($productName === null)
40
            $productName = basenameNoExt ($savePath);
41
42
        if ($productDescription === null)
43
            $productDescription = $productName;
44
45
        if ($productVersion === null)
46
            $productVersion = '1.0';
47
48
        if ($companyName === null)
49
            $companyName = 'Company N';
50
51
        if ($copyright === null)
52
            $copyright = $companyName .' copyright (c) '. date ('Y');
53
54
        return (new WFClass ('WinForms_PHP.WFCompiler', null))->compile ($savePath, $iconPath, $phpCode, $productDescription, $productName, $productVersion, $companyName, $copyright, $callSharpCode, $declareSharpCode, $dictionary, $assemblies)->names;
0 ignored issues
show
Bug Best Practice introduced by
The expression return new VoidEngine\WF...ry, $assemblies)->names could return the type VoidEngine\WFObject which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
Bug Best Practice introduced by
The property names does not exist on VoidEngine\WFObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The method compile() does not exist on VoidEngine\WFClass. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

54
        return (new WFClass ('WinForms_PHP.WFCompiler', null))->/** @scrutinizer ignore-call */ compile ($savePath, $iconPath, $phpCode, $productDescription, $productName, $productVersion, $companyName, $copyright, $callSharpCode, $declareSharpCode, $dictionary, $assemblies)->names;
Loading history...
55
    }
56
57
    public static function loadModule (string $path): bool
58
    {
59
        try
60
        {
61
            (new WFClass ('System.Reflection.Assembly', 'mscorlib'))->loadFrom ($path);
0 ignored issues
show
Bug introduced by
The method loadFrom() does not exist on VoidEngine\WFClass. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

61
            (new WFClass ('System.Reflection.Assembly', 'mscorlib'))->/** @scrutinizer ignore-call */ loadFrom ($path);
Loading history...
62
        }
63
64
        catch (\WinFormsException $e)
0 ignored issues
show
Bug introduced by
The type WinFormsException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
65
        {
66
            return false;
67
        }
68
69
        return true;
70
    }
71
72
    public static function getProperty (int $selector, string $name): array
73
    {
74
        $property = \VoidCore::callMethod (\VoidCore::callMethod ($selector, 'GetType'), 'GetProperty', $name);
1 ignored issue
show
Bug introduced by
The type VoidCore was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
75
76
        if (!is_int ($property))
77
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the type-hinted return array.
Loading history...
78
79
        try
80
        {
81
            $propertyType = \VoidCore::getProperty ($property, ['PropertyType', 'string']);
82
83
            switch ($propertyType)
84
            {
85
                case 'System.String':
86
                    $property = 'string';
87
                break;
88
89
                case 'System.Int32':
90
                case 'System.Int64':
91
                    $property = 'int';
92
                break;
93
94
                case 'System.Double':
95
                    $property = 'double';
96
                break;
97
98
                case 'System.Single':
99
                    $property = 'float';
100
                break;
101
102
                case 'System.Boolean':
103
                    $property = 'bool';
104
                break;
105
106
                case 'System.IntPtr':
107
                    $property = 'handle';
108
                break;
109
110
                case 'System.Drawing.Color':
111
                    $property = 'color';
112
                break;
113
114
                default:
115
                    try
116
                    {
117
                        \VoidCore::getProperty ($selector, [$name, 'int']);
118
119
                        $property = 'int';
120
                    }
121
122
                    catch (\WinFormsException $e)
123
                    {
124
                        return [
125
                            'type'  => 'vrsf',
126
                            'value' => \VoidCore::exportObject (\VoidCore::getProperty ($selector, [$name, 'object']))
127
                        ];
128
                    }
129
                break;
130
            }
131
        }
132
133
        catch (\Throwable $e)
134
        {
135
            $property = 'object';
136
        }
137
138
        return [
139
            'type'  => $property,
140
            'value' => \VoidCore::getProperty ($selector, [$name, $property])
141
        ];
142
    }
143
144
    public static function getObjectEvents (int $object): array
145
    {
146
        $events = [];
147
148
        $props = \VoidCore::callMethod (\VoidCore::callMethod ($object, 'GetType'), 'GetEvents');
149
        $len   = \VoidCore::getProperty ($props, 'Length');
150
151
        for ($i = 0; $i < $len; ++$i)
152
            $events[] = \VoidCore::getProperty (\VoidCore::getArrayValue ($props, $i), 'Name');
153
154
        return $events;
155
    }
156
157
    /**
158
     * При вызове coupleSelector от object->selector указатель может быть обработан в WFObject
159
     * Тогда получается бесконечный цикл вида object->selector->selector->selector->...
160
     * Чтобы этого избежать нужно добавить исключение - переменную $selfSelector
161
     */
162
    public static function coupleSelector ($value, int $selfSelector = null)
163
    {
164
        return is_int ($value) && \VoidCore::objectExists ($value) && $value != $selfSelector ?
165
            new WFObject ($value) : $value;
166
    }
167
168
    public static function uncoupleSelector ($value)
169
    {
170
        return $value instanceof WFObject ?
171
            $value->selector : $value;
0 ignored issues
show
Bug Best Practice introduced by
The property $selector is declared protected in VoidEngine\WFObject. Since you implement __get, consider adding a @property or @property-read.
Loading history...
172
    }
173
}
174
175
class WFObject implements \ArrayAccess
176
{
177
    protected int $selector = 0;
178
    protected $name;
179
180
    public function __construct ($object, $classGroup = false, ...$args)
181
    {
182
        foreach ($args as $id => $arg)
183
            $args[$id] = EngineAdditions::uncoupleSelector ($arg);
184
185
        if (is_string ($object))
186
        {
187
            $this->selector = \VoidCore::createObject ($object, $classGroup, ...$args);
188
            
189
            /*$this->selector = \VoidCore::createObject ($object, $classGroup == 'auto' ?
190
                substr ($object, 0, strrpos ($object, '.')) : $classGroup, ...$args);*/
191
        }
192
193
        elseif (is_int ($object) && \VoidCore::objectExists ($object))
194
            $this->selector = $object;
195
196
        else throw new \Exception ('$object parameter must be string or object selector');
197
    }
198
    
199
    public function __get ($name)
200
	{
201
        if (method_exists ($this, $method = "get_$name"))
202
            $value = $this->$method ();
203
204
        elseif (substr ($name, -5) == 'Event')
205
            $value = Events::getObjectEvent ($this->selector, substr ($name, 0, -5));
0 ignored issues
show
Bug introduced by
The method getObjectEvent() does not exist on VoidEngine\Events. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

205
            /** @scrutinizer ignore-call */ 
206
            $value = Events::getObjectEvent ($this->selector, substr ($name, 0, -5));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
206
207
        elseif (property_exists ($this, $name))
208
            $value = $this->$name;
209
210
        else switch (strtolower ($name))
211
        {
212
            case 'count':
213
            case 'length':
214
                try
215
                {
216
                    return $this->getProperty ('Count');
217
                }
218
219
                catch (\WinFormsException $e)
220
                {
221
                    return $this->getProperty ('Length');
222
                }
223
            break;
224
225
            case 'list':
226
                $size = $this->count;
0 ignored issues
show
Bug Best Practice introduced by
The property count does not exist on VoidEngine\WFObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
227
                $list = [];
228
                
229
				for ($i = 0; $i < $size; ++$i)
230
                    $list[] = EngineAdditions::coupleSelector (\VoidCore::getArrayValue ($this->selector, $i));
231
                
232
                return $list;
233
            break;
1 ignored issue
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
234
235
            case 'names':
236
                $size = $this->count;
237
                $names = [];
238
                
239
                for ($i = 0; $i < $size; ++$i)
240
                    try
241
                    {
242
                        $names[] = \VoidCore::getProperty (\VoidCore::getArrayValue ($this->selector, [$i, 'object']), 'Text');
243
                    }
244
245
                    catch (\WinFormsException $e)
246
                    {
247
                        $names[] = \VoidCore::getArrayValue ($this->selector, [$i, 'string']);
248
                    }
249
                
250
                return $names;
251
            break;
252
253
            default:
254
                $value = $this->getProperty ($name);
255
            break;
256
        }
257
258
        return EngineAdditions::coupleSelector ($value, $this->selector);
259
	}
260
	
261
	public function __set ($name, $value)
262
	{
263
        if (method_exists ($this, $method = "set_$name"))
264
            try
265
            {
266
                return $this->$method ($value);
267
            }
268
269
            # Метод "set_$name" может принимать в качестве параметра объект WFObject
270
            # т.к. наверняка мы не уверены, какой тип ему нужен, то тут требуется дополнительная проверка
271
272
            catch (\Throwable $e)
273
            {
274
                return $value instanceof WFObject ?
275
                    $this->$method ($value->selector) : null;
276
            }
277
278
        elseif (substr ($name, -5) == 'Event')
279
            Events::setObjectEvent ($this->selector, substr ($name, 0, -5), $value);
280
        
281
        else
282
        {
283
            if (is_array ($value) && is_string (current ($value)))
284
                $value = getNetArray ('System.String', $value);
285
286
            $this->setProperty ($name, EngineAdditions::uncoupleSelector ($value));
287
        }
288
    }
289
	
290
	public function __call ($method, $args)
291
	{
292
        $args = array_map (function ($arg)
293
        {
294
            return EngineAdditions::uncoupleSelector ($arg);
295
        }, $args);
296
297
        return EngineAdditions::coupleSelector ($this->callMethod ($method, ...$args), $this->selector);
298
    }
299
300
    public function addRange ($values, $assoc = false): void
301
    {
302
        if (is_array ($values))
303
            foreach ($values as $id => $value)
304
                $this->offsetSet ($assoc ? $id : null, $value);
305
306
        else $this->callMethod ('AddRange', EngineAdditions::uncoupleSelector ($values));
307
    }
308
    
309
    public function offsetSet ($index, $value)
310
	{
311
        try
312
        {
313
            return $index === null ?
314
                $this->callMethod ('Add', EngineAdditions::uncoupleSelector ($value)) :
315
                $this->callMethod ('Insert', $index, EngineAdditions::uncoupleSelector ($value));
316
        }
317
318
        catch (\Throwable $e)
319
        {
320
            return $index === null ?
321
                \VoidCore::setArrayValue ($this->selector, $this->count, EngineAdditions::uncoupleSelector ($value)) :
0 ignored issues
show
Bug Best Practice introduced by
The property count does not exist on VoidEngine\WFObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
322
                \VoidCore::setArrayValue ($this->selector, $index, EngineAdditions::uncoupleSelector ($value));
323
        }
324
    }
325
	
326
	public function offsetGet ($index)
327
	{
328
		return EngineAdditions::coupleSelector (\VoidCore::getArrayValue ($this->selector, $index), $this->selector);
329
    }
330
	
331
	public function offsetUnset ($index): void
332
	{
333
		$this->callMethod ('RemoveAt', $index);
334
    }
335
    
336
    public function offsetExists ($index): bool
337
    {
338
        try
339
        {
340
            $this->offsetGet ($index);
341
        }
342
343
        catch (\Exception $e)
344
        {
345
            return false;
346
        }
347
348
        return true;
349
    }
350
	
351
	public function indexOf ($value): int
352
	{
353
		return $this->callMethod ('IndexOf', EngineAdditions::uncoupleSelector ($value));
354
    }
355
    
356
    public function lastIndexOf ($value): int
357
	{
358
		return $this->callMethod ('LastIndexOf', EngineAdditions::uncoupleSelector ($value));
359
	}
360
	
361
	public function contains ($value): bool
362
	{
363
		return $this->callMethod ('Contains', EngineAdditions::uncoupleSelector ($value));
364
    }
365
366
    public function foreach (callable $callback, string $type = null): void
367
    {
368
        $size = $this->count;
0 ignored issues
show
Bug Best Practice introduced by
The property count does not exist on VoidEngine\WFObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
369
370
        for ($i = 0; $i < $size; ++$i)
371
            $callback (EngineAdditions::coupleSelector (\VoidCore::getArrayValue ($this->selector, $type !== null ? [$i, $type] : $i), $this->selector), $i);
372
    }
373
374
    public function where (callable $comparator, string $type = null): array
375
    {
376
        $size   = $this->count;
0 ignored issues
show
Bug Best Practice introduced by
The property count does not exist on VoidEngine\WFObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
377
        $return = [];
378
379
        for ($i = 0; $i < $size; ++$i)
380
            if ($comparator ($value = EngineAdditions::coupleSelector (\VoidCore::getArrayValue ($this->selector, $type !== null ? [$i, $type] : $i), $this->selector), $i))
381
                $return[] = $value;
382
383
        return $return;
384
    }
385
	
386
    protected function getProperty ($name)
387
    {
388
        try
389
        {
390
            return \VoidCore::getProperty ($this->selector, $name);
391
        }
392
393
        catch (\WinFormsException $e)
394
        {
395
            return \VoidCore::getField ($this->selector, $name);
396
        }
397
    }
398
399
    protected function setProperty ($name, $value)
400
    {
401
        try
402
        {
403
            \VoidCore::setProperty ($this->selector, $name, $value);
404
        }
405
406
        catch (\WinFormsException $e)
407
        {
408
            \VoidCore::setField ($this->selector, $name, $value);
409
        }
410
    }
411
	
412
    protected function callMethod ($method, ...$args)
413
    {
414
        return \VoidCore::callMethod ($this->selector, $method, ...$args);
415
    }
416
	
417
	protected function getArrayProperty ($name, string $type = null)
418
	{
419
        $array  = $this->getProperty ($name);
420
        $size   = \VoidCore::getProperty ($array, 'Length');
421
        $return = [];
422
423
		for ($i = 0; $i < $size; ++$i)
424
            $return[] = \VoidCore::getArrayValue ($array, $type === null ? $i : [$i, $type]);
425
        
426
        \VoidCore::removeObjects ($array);
427
        
428
		return $return;
429
    }
430
431
    public function get_name ()
432
	{
433
		try
434
		{
435
			return $this->getProperty ('Name');
436
        }
437
        
438
		catch (\Throwable $e)
439
		{
440
			return $this->name;
441
		}
442
	}
443
	
444
	public function set_name (string $name)
445
	{
446
		try
447
		{
448
			$this->setProperty ('Name', $name);
449
        }
450
        
451
		catch (\Throwable $e)
452
		{
453
			$this->name = $name;
454
		}
455
	}
456
457
    public function __toString (): string
458
    {
459
        return $this->callMethod ('ToString');
460
    }
461
}
462
463
class WFClass extends WFObject
464
{
465
    public function __construct ($class, $classGroup = false)
466
    {
467
        if (is_string ($class))
468
            $this->selector = \VoidCore::getClass ($class, $classGroup);
469
470
        elseif (is_int ($class) && \VoidCore::objectExists ($class))
471
            $this->selector = $class;
472
473
        else throw new \Exception ('$class parameter must be string or class selector');
474
    }
475
}
476