Completed
Push — master ( 296743...12eab9 )
by Kirill
36:17
created

ExtendBuilder   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 217
Duplicated Lines 40.55 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 76.39%

Importance

Changes 0
Metric Value
wmc 27
lcom 1
cbo 9
dl 88
loc 217
ccs 55
cts 72
cp 0.7639
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A onCompile() 0 15 3
A applyExtender() 0 6 1
B extend() 0 14 7
A extendFields() 26 29 3
A dataFieldExtender() 20 20 3
A extendArguments() 22 25 3
A dataArgumentExtender() 20 20 3
A extendDirectives() 0 18 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * This file is part of Railt package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace Railt\SDL\Reflection\Builder\Processable;
11
12
use Railt\Parser\Ast\NodeInterface;
13
use Railt\SDL\Base\Dependent\Argument\BaseArgumentsContainer;
14
use Railt\SDL\Base\Dependent\BaseArgument;
15
use Railt\SDL\Base\Dependent\BaseField;
16
use Railt\SDL\Base\Dependent\Field\BaseFieldsContainer;
17
use Railt\SDL\Base\Invocations\Directive\BaseDirectivesContainer;
18
use Railt\SDL\Base\Processable\BaseExtend;
19
use Railt\SDL\Contracts\Definitions\Definition;
20
use Railt\SDL\Contracts\Dependent\Argument\HasArguments;
21
use Railt\SDL\Contracts\Dependent\ArgumentDefinition;
22
use Railt\SDL\Contracts\Dependent\Field\HasFields;
23
use Railt\SDL\Contracts\Dependent\FieldDefinition;
24
use Railt\SDL\Contracts\Invocations\Directive\HasDirectives;
25
use Railt\SDL\Contracts\Invocations\DirectiveInvocation;
26
use Railt\SDL\Contracts\Processable\ExtendDefinition;
27
use Railt\SDL\Exceptions\TypeConflictException;
28
use Railt\SDL\Reflection\Builder\DocumentBuilder;
29
use Railt\SDL\Reflection\Builder\Process\Compilable;
30
use Railt\SDL\Reflection\Builder\Process\Compiler;
31
use Railt\SDL\Reflection\Validation\Inheritance;
32
33
/**
34
 * Class ExtendBuilder
35
 */
36
class ExtendBuilder extends BaseExtend implements Compilable
37
{
38
    use Compiler;
39
40
    /**
41
     * ExtendBuilder constructor.
42
     * @param NodeInterface $ast
43
     * @param DocumentBuilder $document
44
     * @throws TypeConflictException
45
     * @throws \Exception
46
     */
47 147
    public function __construct(NodeInterface $ast, DocumentBuilder $document)
48
    {
49 147
        $this->boot($ast, $document);
50 147
    }
51
52
    /**
53
     * @param NodeInterface $ast
54
     * @return bool
55
     * @throws TypeConflictException
56
     * @throws \OutOfBoundsException
57
     */
58 147
    protected function onCompile(NodeInterface $ast): bool
59
    {
60 147
        $type = DocumentBuilder::AST_TYPE_MAPPING[$ast->getName()] ?? null;
61
62 147
        if ($type !== null && ! ($type instanceof ExtendDefinition)) {
63
            /** @var Compilable $virtualType */
64 147
            $virtualType = new $type($ast, $this->getDocument());
65
66 147
            $virtualType->compile();
67
68 147
            $this->applyExtender($virtualType);
69
        }
70
71 65
        return false;
72
    }
73
74
    /**
75
     * @param Definition|Compilable $instance
76
     * @return void
77
     * @throws TypeConflictException
78
     * @throws \OutOfBoundsException
79
     */
80 147
    private function applyExtender(Definition $instance): void
81
    {
82 147
        $this->type = $this->load($instance->getName());
83
84 147
        $this->extend($this->type, $instance);
85 65
    }
86
87
    /**
88
     * @param Definition $original
89
     * @param Definition $extend
90
     * @return void
91
     * @throws TypeConflictException
92
     * @throws \OutOfBoundsException
93
     */
94 147
    private function extend(Definition $original, Definition $extend): void
95
    {
96 147
        if ($original instanceof HasFields && $extend instanceof HasFields) {
97 147
            $this->extendFields($original, $extend);
98
        }
99
100 65
        if ($original instanceof HasDirectives && $extend instanceof HasDirectives) {
101 65
            $this->extendDirectives($original, $extend);
102
        }
103
104 65
        if ($original instanceof HasArguments && $extend instanceof HasArguments) {
105
            $this->extendArguments($original, $extend);
106
        }
107 65
    }
108
109
    /**
110
     * @param HasFields $original
111
     * @param HasFields $extend
112
     * @return void
113
     * @throws \OutOfBoundsException
114
     * @throws TypeConflictException
115
     */
116 147
    private function extendFields(HasFields $original, HasFields $extend): void
117
    {
118 147 View Code Duplication
        foreach ($extend->getFields() as $extendField) {
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...
119 147
            if ($original->hasField($extendField->getName())) {
120
                /**
121
                 * Check field type.
122
                 * @var FieldDefinition $field
123
                 */
124 147
                $field = $original->getField($extendField->getName());
125
126 147
                $this->getValidator(Inheritance::class)->validate($extendField, $field);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Railt\SDL\Reflection\Val...Base\ValidatorInterface as the method validate() does only exist in the following implementations of said interface: Railt\SDL\Reflection\Validation\Base\Factory, Railt\SDL\Reflection\Val...\Base\ValidatorsFactory, Railt\SDL\Reflection\Validation\Definitions, Railt\SDL\Reflection\Val...tions\ArgumentValidator, Railt\SDL\Reflection\Val...BaseDefinitionValidator, Railt\SDL\Reflection\Val...tiveDefinitionValidator, Railt\SDL\Reflection\Val...tiveInvocationValidator, Railt\SDL\Reflection\Val...finitions\EnumValidator, Railt\SDL\Reflection\Val...nitions\ObjectValidator, Railt\SDL\Reflection\Val...assedArgumentsValidator, Railt\SDL\Reflection\Val...nitions\SchemaValidator, Railt\SDL\Reflection\Validation\Inheritance, Railt\SDL\Reflection\Val...aseInheritanceValidator, Railt\SDL\Reflection\Val...heritance\EnumValidator, Railt\SDL\Reflection\Val...eritance\InputValidator, Railt\SDL\Reflection\Val...ance\InterfaceValidator, Railt\SDL\Reflection\Val...ritance\ObjectValidator, Railt\SDL\Reflection\Val...ritance\ScalarValidator, Railt\SDL\Reflection\Val...eritance\UnionValidator, Railt\SDL\Reflection\Val...itance\WrapperValidator, Railt\SDL\Reflection\Validation\Uniqueness, Railt\SDL\Reflection\Val...ar\UniqueValueValidator, Railt\SDL\Reflection\Val...iqueCollectionValidator, Railt\SDL\Reflection\Val...iqueDefinitionValidator.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
127
128 65
                $this->dataFieldExtender()->call($field, $extendField);
129
130
                /**
131
                 * Check field arguments
132
                 */
133 65
                $this->extendArguments($field, $extendField);
134 65
                continue;
135
            }
136
137
            $callee = function () use ($extendField): void {
138
                /** @var BaseFieldsContainer $this */
139
                $this->fields[$extendField->getName()] = $extendField;
140
            };
141
142
            $callee->call($original);
143
        }
144 65
    }
145
146
    /**
147
     * @return \Closure
148
     */
149 View Code Duplication
    private function dataFieldExtender(): \Closure
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...
150
    {
151
        /** @var FieldDefinition|BaseField $field */
152 65
        return function (FieldDefinition $field): void {
153
            /** @var BaseField $this */
154
155
            // Extend type
156 65
            $this->type = $field->type;
0 ignored issues
show
Bug introduced by
Accessing type on the interface Railt\SDL\Contracts\Dependent\FieldDefinition suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
157
158
            // Extend deprecation reason
159 65
            $this->deprecationReason = $field->deprecationReason ?: $this->deprecationReason;
0 ignored issues
show
Bug introduced by
Accessing deprecationReason on the interface Railt\SDL\Contracts\Dependent\FieldDefinition suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
160
161
            // Extend description
162 65
            $this->description = $field->description ?: $this->description;
0 ignored issues
show
Bug introduced by
Accessing description on the interface Railt\SDL\Contracts\Dependent\FieldDefinition suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
163
164
            // NonNull overriding
165 65
            $this->isNonNull        = $field->isNonNull();
166 65
            $this->isListOfNonNulls = $field->isListOfNonNulls();
167 65
        };
168
    }
169
170
    /**
171
     * @param HasArguments|BaseArgumentsContainer|DirectiveInvocation $original
172
     * @param HasArguments|DirectiveInvocation $extend
173
     * @return void
174
     * @throws \OutOfBoundsException
175
     * @throws \Railt\SDL\Exceptions\TypeConflictException
176
     */
177 65
    private function extendArguments($original, $extend): void
178
    {
179 65 View Code Duplication
        foreach ($extend->getArguments() as $extendArgument) {
0 ignored issues
show
Bug introduced by
The method getArguments does only exist in Railt\SDL\Contracts\Depe...t\Argument\HasArguments, but not in Railt\SDL\Contracts\Invo...ons\DirectiveInvocation.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
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...
180 28
            if ($original->hasArgument($extendArgument->getName())) {
0 ignored issues
show
Bug introduced by
The method hasArgument does only exist in Railt\SDL\Base\Dependent...t\Argument\HasArguments, but not in Railt\SDL\Contracts\Invo...ons\DirectiveInvocation.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
181
                /**
182
                 * Check field type.
183
                 * @var ArgumentDefinition $argument
184
                 */
185 28
                $argument = $original->getArgument($extendArgument->getName());
0 ignored issues
show
Bug introduced by
The method getArgument does only exist in Railt\SDL\Base\Dependent...t\Argument\HasArguments, but not in Railt\SDL\Contracts\Invo...ons\DirectiveInvocation.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
186
187 28
                $this->getValidator(Inheritance::class)->validate($extendArgument, $argument);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Railt\SDL\Reflection\Val...Base\ValidatorInterface as the method validate() does only exist in the following implementations of said interface: Railt\SDL\Reflection\Validation\Base\Factory, Railt\SDL\Reflection\Val...\Base\ValidatorsFactory, Railt\SDL\Reflection\Validation\Definitions, Railt\SDL\Reflection\Val...tions\ArgumentValidator, Railt\SDL\Reflection\Val...BaseDefinitionValidator, Railt\SDL\Reflection\Val...tiveDefinitionValidator, Railt\SDL\Reflection\Val...tiveInvocationValidator, Railt\SDL\Reflection\Val...finitions\EnumValidator, Railt\SDL\Reflection\Val...nitions\ObjectValidator, Railt\SDL\Reflection\Val...assedArgumentsValidator, Railt\SDL\Reflection\Val...nitions\SchemaValidator, Railt\SDL\Reflection\Validation\Inheritance, Railt\SDL\Reflection\Val...aseInheritanceValidator, Railt\SDL\Reflection\Val...heritance\EnumValidator, Railt\SDL\Reflection\Val...eritance\InputValidator, Railt\SDL\Reflection\Val...ance\InterfaceValidator, Railt\SDL\Reflection\Val...ritance\ObjectValidator, Railt\SDL\Reflection\Val...ritance\ScalarValidator, Railt\SDL\Reflection\Val...eritance\UnionValidator, Railt\SDL\Reflection\Val...itance\WrapperValidator, Railt\SDL\Reflection\Validation\Uniqueness, Railt\SDL\Reflection\Val...ar\UniqueValueValidator, Railt\SDL\Reflection\Val...iqueCollectionValidator, Railt\SDL\Reflection\Val...iqueDefinitionValidator.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
188
189 28
                $this->dataArgumentExtender()->call($argument, $extendArgument);
190
191 28
                continue;
192
            }
193
194
            $callee = function () use ($extendArgument): void {
195
                /** @var BaseArgumentsContainer $this */
196
                $this->arguments[$extendArgument->getName()] = $extendArgument;
197
            };
198
199
            $callee->call($original);
200
        }
201 65
    }
202
203
    /**
204
     * @return \Closure
205
     */
206 View Code Duplication
    private function dataArgumentExtender(): \Closure
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...
207
    {
208
        /** @var ArgumentDefinition|BaseArgument $argument */
209 28
        return function (ArgumentDefinition $argument): void {
210
            /** @var BaseArgument $this */
211
212
            // Extend type
213 28
            $this->type = $argument->type;
0 ignored issues
show
Bug introduced by
Accessing type on the interface Railt\SDL\Contracts\Dependent\ArgumentDefinition suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
214
215
            // Extend deprecation reason
216 28
            $this->deprecationReason = $argument->deprecationReason ?: $this->deprecationReason;
0 ignored issues
show
Bug introduced by
Accessing deprecationReason on the interface Railt\SDL\Contracts\Dependent\ArgumentDefinition suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
217
218
            // Extend description
219 28
            $this->description = $argument->description ?: $this->description;
0 ignored issues
show
Bug introduced by
Accessing description on the interface Railt\SDL\Contracts\Dependent\ArgumentDefinition suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
220
221
            // NonNull overriding
222 28
            $this->isNonNull        = $argument->isNonNull();
223 28
            $this->isListOfNonNulls = $argument->isListOfNonNulls();
224 28
        };
225
    }
226
227
    /**
228
     * @param HasDirectives|BaseDirectivesContainer $original
229
     * @param HasDirectives $extend
230
     * @return void
231
     * @throws \OutOfBoundsException
232
     * @throws TypeConflictException
233
     */
234 65
    private function extendDirectives(HasDirectives $original, HasDirectives $extend): void
235
    {
236 65
        foreach ($extend->getDirectives() as $extendDirective) {
237
            if ($original->hasDirective($extendDirective->getName())) {
238
                /** @var DirectiveInvocation $directive */
239
                $directive = $original->getDirective($extendDirective->getName());
0 ignored issues
show
Deprecated Code introduced by
The method Railt\SDL\Contracts\Invo...ectives::getDirective() has been deprecated with message: Use ...->getDirectives($name) instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
240
                $this->extendArguments($directive, $extendDirective);
241
                continue;
242
            }
243
244
            $callee = function () use ($extendDirective): void {
245
                /** @var BaseArgumentsContainer $this */
246
                $this->arguments[$extendDirective->getName()] = $extendDirective;
247
            };
248
249
            $callee->call($original);
250
        }
251 65
    }
252
}
253