Completed
Push — master ( 31785d...5192f1 )
by Richard
06:45
created

ContainText::compile()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 52
Code Lines 42

Duplication

Lines 7
Ratio 13.46 %

Code Coverage

Tests 32
CRAP Score 4.2678

Importance

Changes 0
Metric Value
dl 7
loc 52
ccs 32
cts 43
cp 0.7442
rs 8.9408
c 0
b 0
f 0
cc 4
eloc 42
nc 3
nop 2
crap 4.2678

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/******************************************************************************
3
 * An implementation of dicto (scg.unibe.ch/dicto) in and for PHP.
4
 *
5
 * Copyright (c) 2016 Richard Klees <[email protected]>
6
 *
7
 * This software is licensed under The MIT License. You should have received
8
 * a copy of the license along with the code.
9
 */
10
11
namespace Lechimp\Dicto\Rules;
12
13
use Lechimp\Dicto\Analysis\Index;
14
use Lechimp\Dicto\Analysis\Violation;
15
use Lechimp\Dicto\Definition\ArgumentParser;
16
use Lechimp\Dicto\Indexer\ListenerRegistry;
17
use Lechimp\Dicto\Graph\Node;
18
use Lechimp\Dicto\Graph;
19
20
/**
21
 * This checks wheather there is some text in some entity.
22
 *
23
 * TODO: Test if ContainText finds text in files.
24
 */
25
class ContainText extends Schema {
26
    /**
27
     * @inheritdoc
28
     */
29 42
    public function name() {
30 42
        return "contain text";
31
    } 
32
33
    /**
34
     * @inheritdoc
35
     */
36 7
    public function fetch_arguments(ArgumentParser $parser) {
37 7
        $regexp = $parser->fetch_string();
38 7
        return array($regexp);
39
    }
40
41
    /**
42
     * @inheritdoc
43
     */
44 16 View Code Duplication
    public function arguments_are_valid(array &$arguments) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
45 16
        if (count($arguments) != 1) {
46
            return false;
47
        }
48 16
        $regexp = $arguments[0];
49 16
        if (!is_string($regexp) || @preg_match("%$regexp%", "") === false) {
50
            return false;
51
        }
52 16
        return true;
53
    }
54
55
    /**
56
     * @inheritdoc
57
     */
58 8
    public function compile(Index $index, Rule $rule) {
59 8
        $mode = $rule->mode();
60 8
        $filter = $rule->checked_on()->compile();
61 8
        $regexp = $rule->argument(0);
62
        $regexp_filter = function(Graph\Relation $r) use ($regexp) {
0 ignored issues
show
Unused Code introduced by
$regexp_filter is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
63
            $start_line = $r->property("start_line");
64
            $end_line = $r->property("end_line");
65
            $source = implode
66
                ( "\n"
67
                , array_slice
68
                    ( $r->target()->property("source")
69
                    , $start_line - 1
70
                    , $end_line - $start_line
71
                    )
72
                );
73
            return preg_match("%$regexp%", $source) == 1;
74 8
        };
75
76 8
        if ($mode == Rule::MODE_CANNOT || $mode == Rule::MODE_ONLY_CAN) {
77 5
            return $index->query()
78 5
                ->filter($filter)
79 5
                ->expand_relations(["defined in"])
80 5
                ->filter($this->regexp_source_filter($regexp, false))
81
                ->extract(function($e,&$r) use ($rule, $regexp) {
82 1
                    $matches = [];
83 1
                    $source = $this->get_source_for($e);
84 1
                    preg_match("%(.*)$regexp%", $source, $matches);
85
86 1
                    $file = $e->target();
87 1
                    $r["file"] = $file->property("path");
88 1
                    $start_line = $e->property("start_line");
89 1
                    $found_at_line = substr_count($matches[0], "\n") + 1;
90 1
                    $line = $start_line + $found_at_line;
91 1
                    $r["line"] = $line + 1;
92 2
                    $r["source"] = $file->property("source")[$line];
93 5
                });
94
        }
95 3
        if ($mode == Rule::MODE_MUST) {
96 3
            return $index->query()
97 3
                ->filter($filter)
98 3
                ->expand_relations(["defined in"])
99 3
                ->filter($this->regexp_source_filter($regexp, true))
100 View Code Duplication
                ->extract(function($e,&$r) use ($rule) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
101 1
                    $file = $e->target();
102 1
                    $r["file"] = $file->property("path");
103 1
                    $line = $e->property("start_line");
104 1
                    $r["line"] = $line;
105 1
                    $r["source"] = $file->property("source")[$line - 1];
106 3
                });
107
        }
108
        throw new \LogicException("Unknown rule mode: '$mode'");
109
    }
110
111
    // Helpers for compile
112
113 5
    protected function get_source_for(Graph\Relation $r) {
114 5
        assert('$r->type() == "defined in"');
115 5
        $start_line = $r->property("start_line");
116 5
        $end_line = $r->property("end_line");
117
        return implode
118 5
            ( "\n"
119 5
            , array_slice
120 5
                ( $r->target()->property("source")
121 5
                , $start_line - 1
122 5
                , $end_line - $start_line
123 5
                )
124 5
            );
125
    }
126
127 8
    protected function regexp_source_filter($regexp, $negate) {
128 8
        assert('is_string($regexp)');
129 8
        assert('is_bool($negate)');
130 8
        return function(Graph\Relation $r) use ($regexp, $negate) {
131 5
            $source = $this->get_source_for($r);
132 5
            if(!$negate) {
133 3
                return preg_match("%$regexp%", $source) == 1;
134
            }
135
            else {
136 2
                return preg_match("%$regexp%", $source) == 0;
137
            }
138 8
        };
139
    }
140
141
    /**
142
     * @inheritdoc
143
     */
144 8
    public function pprint(Rule $rule) {
145 8
        return $this->name().' "'.$rule->argument(0).'"';
146
    }
147
148
    /**
149
     * No listeners required for contains text. 
150
     *
151
     * @inheritdoc
152
     */
153 7
    public function register_listeners(ListenerRegistry $registry) {
154 7
    }
155
156
}
157