Test Failed
Branch master (44c6e4)
by stéphane
09:11
created

Builder::buildNodeList()   B

Complexity

Conditions 9
Paths 25

Size

Total Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 33
rs 8.0555
c 0
b 0
f 0
cc 9
nc 25
nop 2
1
<?php
2
3
namespace Dallgoot\Yaml;
4
5
use Dallgoot\Yaml\{Yaml as Y, Regex as R};
6
7
/**
8
 * Constructs the result (YamlObject or array) according to every Node and respecting value
9
 *
10
 * @author  Stéphane Rebai <[email protected]>
11
 * @license Apache 2.0
12
 * @link    TODO : url to specific online doc
13
 */
14
final class Builder
15
{
16
    private static $_root;
0 ignored issues
show
Coding Style introduced by
$_root does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
17
    private static $_debug;
0 ignored issues
show
Coding Style introduced by
$_debug does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
18
19
    const ERROR_NO_KEYNAME = self::class.": key has NO IDENTIFIER on line %d";
20
    const INVALID_DOCUMENT = self::class.": DOCUMENT %d can NOT be a mapping AND a sequence";
21
22
    /**
23
     * Builds a file.  check multiple documents & split if more than one documents
24
     *
25
     * @param   Node   $_root      The root node : Node with Node->type === YAML::ROOT
26
     * @param   int   $_debug      the level of debugging requested
27
     *
28
     * @return array|YamlObject      list of documents or just one.
29
     * @todo  implement splitting on YAML::DOC_END also
30
     */
31
    public static function buildContent(Node $_root, int $_debug)
0 ignored issues
show
Coding Style introduced by
$_root does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
32
    {
33
        self::$_debug = $_debug;
0 ignored issues
show
Coding Style introduced by
$_debug does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
34
        $totalDocStart = 0;
35
        $documents = [];
36
        if ($_root->value instanceof Node) {
0 ignored issues
show
Coding Style introduced by
$_root does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
37
            $q = new NodeList;
38
            $q->push($_root->value);
0 ignored issues
show
Coding Style introduced by
$_root does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
39
            self::$_root = new YamlObject;
40
            $tmp =  self::buildNodeList($q, self::$_root);
41
            return $tmp;
42
        }
43
        $_root->value instanceof NodeList && $_root->value->setIteratorMode(NodeList::IT_MODE_DELETE);
0 ignored issues
show
Coding Style introduced by
$_root does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
44
        foreach ($_root->value as $child) {
0 ignored issues
show
Coding Style introduced by
$_root does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
Bug introduced by
The expression $_root->value of type object<Dallgoot\Yaml\NodeList>|null|string is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
45
            if ($child->type & Y::DOC_START) $totalDocStart++;
46
            //if 0 or 1 DOC_START = we are still in first document
47
            $currentDoc = $totalDocStart > 1 ? $totalDocStart - 1 : 0;
48
            if (!isset($documents[$currentDoc])) $documents[$currentDoc] = new NodeList();
49
            $documents[$currentDoc]->push($child);
50
        }
51
        $content = [];
52
        foreach ($documents as $num => $list) {
53
            try {
54
                self::$_root = new YamlObject;
55
                $content[] = self::buildNodeList($list, self::$_root);
56
            } catch (\Exception $e) {
57
                throw new \ParseError(sprintf(self::INVALID_DOCUMENT, $num));
0 ignored issues
show
Unused Code introduced by
The call to ParseError::__construct() has too many arguments starting with sprintf(self::INVALID_DOCUMENT, $num).

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
58
            }
59
        }
60
        return count($content) === 1 ? $content[0] : $content;
61
    }
62
63
    /**
64
     * Generic function to distinguish between Node and NodeList
65
     *
66
     * @param Node|NodeList $node   The node.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $node not be object?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
67
     * @param mixed         $parent The parent
68
     *
69
     * @return mixed  ( description_of_the_return_value )
70
     */
71
    private static function build(object $node, &$parent = null)
72
    {
73
        if ($node instanceof NodeList) return self::buildNodeList($node, $parent);
74
        return self::buildNode($node, $parent);
75
    }
76
77
    /**
78
     * Builds a node list.
79
     *
80
     * @param NodeList $node   The node
81
     * @param mixed    $parent The parent
82
     *
83
     * @return mixed    The parent (object|array) or a string representing the NodeList.
84
     */
85
    private static function buildNodeList(NodeList $node, &$parent=null)
86
    {
87
        $node->forceType();
88
        if ($node->type & (Y::RAW | Y::LITTERALS)) {
89
            return self::buildLitteral($node, (int) $node->type);
90
        }
91
        $action = function ($child, &$parent, &$out) {
92
            self::build($child, $out);
93
        };
94
        if ($node->type & (Y::COMPACT_MAPPING|Y::MAPPING|Y::SET)) {
95
            $out = $parent ?? new \StdClass;
96
        } elseif ($node->type & (Y::COMPACT_SEQUENCE|Y::SEQUENCE)) {
97
            $out = $parent ?? [];
98
        } else {
99
            $out = '';
100
            $action = function ($child, &$parent, &$out) {
101
                if ($child->type & (Y::SCALAR|Y::QUOTED)) {
102
                    if ($parent) {
103
                        $parent->setText(self::build($child));
104
                    } else {
105
                        $out .= self::build($child);
106
                    }
107
                }
108
            };
109
        }
110
        foreach ($node as $child) {
111
            $action($child, $parent, $out);
112
        }
113
        if ($node->type & (Y::COMPACT_SEQUENCE|Y::COMPACT_MAPPING)) {
114
            $out = new Compact($out);
115
        }
116
        return is_null($out) ? $parent : $out;
117
    }
118
119
    /**
120
     * Builds a node.
121
     *
122
     * @param Node    $node    The node of any Node->type
123
     * @param mixed  $parent  The parent
124
     *
125
     * @return mixed  The node value as scalar, array or object or null to otherwise.
126
     */
127
    private static function buildNode(Node $node, &$parent)
128
    {
129
        extract((array) $node, EXTR_REFS);
0 ignored issues
show
Bug introduced by
(array) $node cannot be passed to extract() as the parameter $var_array expects a reference.
Loading history...
130
        if ($type & (Y::REF_DEF | Y::REF_CALL)) {
131
            if (is_object($value)) {
132
                $tmp = self::build($value, $parent) ?? $parent;
133
            } else {
134
                $tmp = Node2PHP::get($node);
135
            }
136
            if ($type === Y::REF_DEF) self::$_root->addReference($identifier, $tmp);
137
            return self::$_root->getReference($identifier);
138
        }
139
        if ($type & (Y::COMPACT_MAPPING|Y::COMPACT_SEQUENCE)) {
140
            return self::buildNodeList($node->value, $parent);
0 ignored issues
show
Bug introduced by
It seems like $node->value can also be of type null or object<Dallgoot\Yaml\Node> or string; however, Dallgoot\Yaml\Builder::buildNodeList() does only seem to accept object<Dallgoot\Yaml\NodeList>, 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...
141
        }
142
        if ($type & Y::COMMENT) self::$_root->addComment($node->line, $node->value);
143
        $typesActions = [Y::DIRECTIVE => 'buildDirective',
144
                         Y::ITEM      => 'buildItem',
145
                         Y::KEY       => 'buildKey',
146
                         Y::SET_KEY   => 'buildSetKey',
147
                         Y::SET_VALUE => 'buildSetValue',
148
                         Y::TAG       => 'buildTag',
149
        ];
150
        if (isset($typesActions[$type])) {
151
            return self::{$typesActions[$type]}($node, $parent);
152
        }
153
        return is_object($value) ? self::build($value, $parent) : Node2PHP::get($node);
154
    }
155
156
    /**
157
     * Builds a key and set the property + value to the given parent
158
     *
159
     * @param Node $node       The node with type YAML::KEY
160
     * @param object|array $parent       The parent
0 ignored issues
show
Documentation introduced by
Should the type for parameter $parent not be object|array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
161
     *
162
     * @throws \ParseError if Key has no name(identifier) Note: empty string is allowed
163
     * @return null
164
     */
165
    private static function buildKey(Node $node, &$parent=null)
166
    {
167
        extract((array) $node, EXTR_REFS);
0 ignored issues
show
Bug introduced by
(array) $node cannot be passed to extract() as the parameter $var_array expects a reference.
Loading history...
168
        if (is_null($identifier)) {
169
            throw new \ParseError(sprintf(self::ERROR_NO_KEYNAME, $line));
0 ignored issues
show
Unused Code introduced by
The call to ParseError::__construct() has too many arguments starting with sprintf(self::ERROR_NO_KEYNAME, $line).

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
170
        } else {
171
            if ($value instanceof Node) {
172
                if ($value->type & (Y::ITEM|Y::KEY)) {
173
                    $list = new NodeList();
174
                    $list->push($value);
175
                    $list->type = $value->type & Y::ITEM ? Y::SEQUENCE : Y::MAPPING;
176
                    $value = $list;
177
                } else {
178
                    $result = self::build($value);
179
                }
180
            }
181
            if ($value instanceof NodeList) {
182
                $childTypes = $value->getTypes();
183
                if (is_null($value->type) && $childTypes & Y::SCALAR && !($childTypes & Y::COMMENT)) {
184
                    $result = self::buildLitteral($value, Y::LITT_FOLDED);
185
                } else {
186
                    $result = self::buildNodeList($value);
187
                }
188
            }
189
            if (is_null($parent)) {
190
                return $result;
191
            } else {
192
                if (is_array($parent)) {
193
                    $parent[$identifier] = $result;
194
                } else {
195
                    $parent->{$identifier} = $result;
196
                }
197
            }
198
        }
199
    }
200
201
    /**
202
     * Builds an item. Adds the item value to the parent array|Iterator
203
     *
204
     * @param      Node        $node    The node with type YAML::ITEM
205
     * @param      array|\Iterator      $parent  The parent
206
     *
207
     * @throws     \Exception  if parent is another type than array or object Iterator
208
     * @return null
209
     */
210
    private static function buildItem(Node $node, &$parent)
211
    {
212
        extract((array) $node, EXTR_REFS);//var_dump(__METHOD__);
0 ignored issues
show
Bug introduced by
(array) $node cannot be passed to extract() as the parameter $var_array expects a reference.
Loading history...
213
        if (!is_array($parent) && !($parent instanceof \ArrayIterator)) {
214
            throw new \Exception("parent must be an Iterable not ".(is_object($parent) ? get_class($parent) : gettype($parent)), 1);
215
        }
216
        $ref = $parent instanceof \ArrayIterator ? $parent->getArrayCopy() : $parent;
217
        $numKeys = array_filter(array_keys($ref), 'is_int');
218
        $key = count($numKeys) > 0 ? max($numKeys) + 1 : 0;
219
        if ($value instanceof Node) {
220
            if($value->type & Y::KEY) {
221
                self::buildKey($node->value, $parent);
0 ignored issues
show
Bug introduced by
It seems like $node->value can also be of type null or object<Dallgoot\Yaml\NodeList> or string; however, Dallgoot\Yaml\Builder::buildKey() does only seem to accept object<Dallgoot\Yaml\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...
222
                return;
223
            } elseif ($value->type & Y::ITEM) {
224
                $list = new NodeList();
225
                $list->push($value);
226
                $list->type = Y::SEQUENCE;
227
                $result = self::buildNodeList($list);
228
            } else {
229
                $result = self::build($value);
230
            }
231
        } elseif ($value instanceof NodeList) {
232
            $result = self::buildNodeList($value);
233
        }
234
        $parent[$key] = $result;
235
    }
236
237
238
    /**
239
     * Builds a litteral (folded or not) or any NodeList that has YAML::RAW type (like a multiline value)
240
     *
241
     * @param      NodeList  $children  The children
0 ignored issues
show
Bug introduced by
There is no parameter named $children. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
242
     * @param      integer   $type      The type
243
     *
244
     * @return     string    The litteral.
245
     * @todo : Example 6.1. Indentation Spaces  spaces must be considered as content
246
     */
247
    private static function buildLitteral(NodeList $list, int $type):string
248
    {
249
        $list->rewind();
250
        $refIndent = $list->current()->indent;
251
        //remove trailing blank
252
        while ($list->top()->type & Y::BLANK) {
253
            $list->pop();
254
        }
255
        $result = '';
256
        $separator = '';
257
        if ($type & Y::LITT)         $separator = "\n";
258
        if ($type & Y::LITT_FOLDED)  $separator = ' ';
259
        foreach ($list as $child) {
260
            if ($child->value instanceof NodeList) {
261
                $result .= self::buildLitteral($child->value, $type).$separator;
262
            } else {
263
                $val = $child->type & (Y::SCALAR|Y::BLANK) ? $child->value : substr($child->raw, $refIndent);
264
                if ($type & Y::LITT_FOLDED && ($child->indent > $refIndent || ($child->type & Y::BLANK))) {
265
                    if ($result[-1] === $separator)
266
                        $result[-1] = "\n";
267
                    if ($result[-1] === "\n")
268
                        $result .= $val;
269
                    continue;
270
                }
271
                $result .= $val.$separator;
272
            }
273
        }
274
        return rtrim($result);
275
    }
276
277
    /**
278
     * Builds a set key.
279
     *
280
     * @param      Node        $node    The node of type YAML::SET_KEY.
281
     * @param      object      $parent  The parent
282
     *
283
     * @throws     \Exception  if a problem occurs during serialisation (json format) of the key
284
     */
285
    private function buildSetKey(Node $node, &$parent)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
286
    {
287
        $built = is_object($node->value) ? self::build($node->value) : null;
0 ignored issues
show
Documentation introduced by
$node->value is of type object<Dallgoot\Yaml\Nod...Dallgoot\Yaml\NodeList>, but the function expects a object<Dallgoot\Yaml\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
288
        $stringKey = is_string($built) && Regex::isProperlyQuoted($built) ? trim($built, '\'" '): $built;
289
        $key = json_encode($stringKey, JSON_PARTIAL_OUTPUT_ON_ERROR|JSON_UNESCAPED_SLASHES);
290
        // if (empty($key)) throw new \Exception("Cant serialize complex key: ".var_export($node->value, true), 1);
291
        $parent->{trim($key, '\'" ')} = null;
292
    }
293
294
    /**
295
     * Builds a set value.
296
     *
297
     * @param      Node    $node    The node of type YAML::SET_VALUE
298
     * @param      object  $parent  The parent (the document object or any previous object created through a mapping key)
299
     */
300
    private function buildSetValue(Node $node, &$parent)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
301
    {
302
        $prop = array_keys(get_object_vars($parent));
303
        $key = end($prop);
304
        if ($node->value->type & (Y::ITEM|Y::KEY|Y::SEQUENCE|Y::MAPPING)) {
305
            $p = $node->value->type === Y::ITEM ? [] : new \StdClass;
306
            self::build($node->value, $p);
0 ignored issues
show
Documentation introduced by
$node->value is of type object<Dallgoot\Yaml\Nod...t\Yaml\NodeList>|string, but the function expects a object<Dallgoot\Yaml\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
307
        } else {
308
            $p = self::build($node->value, $parent->{$key});
0 ignored issues
show
Documentation introduced by
$node->value is of type object<Dallgoot\Yaml\Nod...t\Yaml\NodeList>|string, but the function expects a object<Dallgoot\Yaml\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
309
        }
310
        $parent->{$key} = $p;
311
    }
312
313
    /**
314
     * Builds a tag and its value (also built) and encapsulates them in a Tag object.
315
     *
316
     * @param      Node    $node    The node of type YAML::TAG
317
     * @param      mixed  $parent  The parent
318
     *
319
     * @return     Tag|null     The tag object of class Dallgoot\Yaml\Tag.
320
     */
321
    private static function buildTag(Node $node, &$parent)
322
    {
323
        $name = (string) $node->identifier;
324
        if ($parent === self::$_root && empty($node->value)) {
325
            $parent->addTag($name);
326
            return;
327
        }
328
        $target = $node->value;
329
        if ($node->value instanceof Node) {
330
            if ($node->value->type & (Y::KEY|Y::ITEM)) {
331
                if (is_null($parent)) {
332
                    $target = new NodeList;
333
                    $target->push($node->value);
334
                    $target->type = $node->value->type & Y::KEY ? Y::MAPPING : Y::SEQUENCE;
335
                } else {
336
                    $node->value->type & Y::KEY ? self::buildKey($node->value, $parent) : self::buildItem($node->value, $parent);
337
                }
338
            }
339
        }
340
        //TODO: have somewhere a list of common tags and their treatment
341
        // if (in_array($node->identifier, ['!binary', '!str'])) {
342
        //     $target->type = Y::RAW;
343
        // }
344
        return new Tag($name, is_object($target) ? self::build($target) : null);
0 ignored issues
show
Documentation introduced by
$target is of type object<Dallgoot\Yaml\Nod...Dallgoot\Yaml\NodeList>, but the function expects a object<Dallgoot\Yaml\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
345
    }
346
347
    /**
348
     * Builds a directive. NOT IMPLEMENTED YET
349
     *
350
     * @param      Node  $node    The node
351
     * @param      mixed  $parent  The parent
352
     * @todo implement if requested
353
     */
354
    private function buildDirective(Node $node, $parent)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
Unused Code introduced by
The parameter $node is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $parent is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
355
    {
356
        // TODO : implement
357
    }
358
}
359