Passed
Pull Request — master (#45)
by X
02:29
created

NameSpaceConverter   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 44
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
dl 0
loc 44
rs 10
c 0
b 0
f 0
wmc 11
lcom 1
cbo 7

1 Method

Rating   Name   Duplication   Size   Complexity  
C leaveNode() 0 41 11
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 16 and the first side effect is on line 4.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
// see: https://github.com/nikic/PHP-Parser/blob/master/doc/2_Usage_of_basic_components.markdown
3
4
require __DIR__ . '/../vendor/autoload.php';
5
6
use PhpParser\BuilderFactory;
7
use PhpParser\Comment;
8
use PhpParser\Node;
9
use PhpParser\Node\Expr;
10
use PhpParser\Node\Stmt;
11
use PhpParser\NodeTraverser;
12
use PhpParser\NodeVisitor\NameResolver;
13
use PhpParser\ParserFactory;
14
use PhpParser\PrettyPrinter;
15
16
class NameSpaceConverter extends \PhpParser\NodeVisitorAbstract
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
17
{
18
    public function leaveNode(Node $node) {
19
        if ($node instanceof Node\Name) {
20
            return new Node\Name(str_replace('\\', '_', $node->toString()));
21
        }
22
        if ($node instanceof Stmt\Class_ ||
23
            $node instanceof Stmt\Interface_ ||
24
            $node instanceof Stmt\Function_) {
25
            $node->name = str_replace('\\', '_', $node->namespacedName->toString());
26
        }
27
        if ($node instanceof Stmt\Const_) {
28
            foreach ($node->consts as $const) {
29
                $const->name = str_replace('\\', '_', $const->namespacedName->toString());
30
            }
31
        }
32
        if ($node instanceof Stmt\Namespace_) {
33
            return $node->stmts;
34
        }
35
        if ($node instanceof Stmt\Use_) {
36
            return NodeTraverser::REMOVE_NODE;
37
        }
38
        if ($node instanceof Stmt\ClassMethod) {
39
            $doc = $node->getDocComment();
40
            if (is_null($doc)) {
41
                return $node;
42
            }
43
            $search = [
44
                '\xKerman\Restricted\UnserializeFailedException',
45
                '\InvalidArgumentException',
46
            ];
47
            $replace = [
48
                'xKerman_Restricted_UnserializeFailedException',
49
                'InvalidArgumentException',
50
            ];
51
            $newDoc = new Comment\Doc(
52
                str_replace($search, $replace, $doc->getText()),
53
                $doc->getLine(),
54
                $doc->getFilePos()
55
            );
56
            $node->setAttribute('comments', [$newDoc]);
57
        }
58
    }
59
}
60
61
function convert($inDir, $outDir)
62
{
63
    $factory = new ParserFactory();
64
    $parser = $factory->create(ParserFactory::ONLY_PHP5);
65
    $traverser = new NodeTraverser();
66
    $printer = new PrettyPrinter\Standard();
67
68
    $traverser->addVisitor(new NameResolver());
69
    $traverser->addVisitor(new NameSpaceConverter());
70
71
    $files = new \RecursiveIteratorIterator(new RecursiveDirectoryIterator($inDir));
72
    $files = new \RegexIterator($files, '/\.php\z/');
73
74
    if (!file_exists($outDir)) {
75
        mkdir($outDir, 0755, true);
76
    }
77
78
    foreach ($files as $file) {
79
        try {
80
            $code = file_get_contents($file);
81
            $statements = $parser->parse($code);
82
            $statements = $traverser->traverse($statements);
0 ignored issues
show
Bug introduced by
It seems like $statements can also be of type null; however, PhpParser\NodeTraverser::traverse() does only seem to accept array<integer,object<PhpParser\Node>>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
83
            file_put_contents(
84
                $outDir . '/xKerman_Restricted_' . $file->getFileName(),
85
                $printer->prettyPrintFile($statements)
86
            );
87
        } catch (PhpParser\Error $e) {
88
            echo 'Parsee Error: ', $e->getMessage();
89
        }
90
    }
91
}
92
93
function generateBootstrap($dir)
94
{
95
    $code = <<<'PHPCODE'
96
<?php
97
98
function xKerman_Restricted_bootstrap($classname)
99
{
100
    if (strpos($classname, 'xKerman_Restricted_') !== 0) {
101
        return false;
102
    }
103
    $path = dirname(__FILE__) . "/{$classname}.php";
104
    if (file_exists($path)) {
105
        require_once $path;
106
    }
107
}
108
109
spl_autoload_register('xKerman_Restricted_bootstrap');
110
require_once dirname(__FILE__) . '/xKerman_Restricted_function.php';
111
PHPCODE;
112
113
    file_put_contents(
114
        $dir . '/bootstrap.php',
115
        $code
116
    );
117
}
118
119
// main
120
convert(__DIR__ . '/../src', __DIR__ . '/../generated/src');
121
convert(__DIR__ . '/../test', __DIR__ . '/../generated/test');
122
generateBootstrap(__DIR__ . '/../generated/src');
123