Skip to content

Commit

Permalink
Don't use closure binding for public methods and properties
Browse files Browse the repository at this point in the history
  • Loading branch information
mabar committed Jan 21, 2025
1 parent 2beb12f commit 62fcfac
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 11 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Callbacks
- receive `FieldContext` (callback-specific) instead of `FieldContext` and `ObjectContext` instead of
`MappedObjectContext`
- are not called via closure binding when public
- Contexts
- `TypeContext`, `MappedObjectContext` and `FieldContext` replaced with `ServicesContext`, `DynamicContext`,
`PropertyContext`, `FieldContext` (for callbacks) and `ObjectContext` (callback-specific)
Expand Down Expand Up @@ -56,6 +57,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- creates `MappedObjectType` only when necessary (performance optimization)
- automatic meta cache reset after main `process()` call (performance optimization) replaced with `reset()`
method
- properties are not set/unset via closure binding when public

### Removed

Expand Down
13 changes: 10 additions & 3 deletions src/Callbacks/BaseCallback.php
Original file line number Diff line number Diff line change
Expand Up @@ -335,17 +335,24 @@ public static function invoke(
}

$method = $args->method;
$methodInst = $declaringClass->getMethod($method);

if ($args->isStatic) {
$class = $holder->getClass();
$callbackOutput = (static fn () => $class::$method($data, $context))

$callbackOutput = $methodInst->isPublic()
? $class::$method($data, $context)

Check failure on line 344 in src/Callbacks/BaseCallback.php

View workflow job for this annotation

GitHub Actions / Static analysis (ubuntu-latest, 8.4)

Ignored error pattern #^Variable static method call on class-string\<Orisai\\ObjectMapper\\MappedObject\>\.$# in path /home/runner/work/object-mapper/object-mapper/src/Callbacks/BaseCallback.php is expected to occur 1 time, but occurred 2 times.
: (static fn () => $class::$method($data, $context))

Check failure on line 345 in src/Callbacks/BaseCallback.php

View workflow job for this annotation

GitHub Actions / Static analysis (ubuntu-latest, 8.4)

Variable static method call on class-string<Orisai\ObjectMapper\MappedObject>.
->bindTo(null, $declaringClass->getName())();
} else {
$instance = $holder->getInstance();
// Closure with bound instance cannot be static

// phpcs:disable SlevomatCodingStandard.Functions.StaticClosure.ClosureNotStatic
$callbackOutput = (fn () => $instance->$method($data, $context))
$callbackOutput = $methodInst->isPublic()
? $instance->$method($data, $context)

Check failure on line 352 in src/Callbacks/BaseCallback.php

View workflow job for this annotation

GitHub Actions / Static analysis (ubuntu-latest, 8.4)

Ignored error pattern #^Variable method call on Orisai\\ObjectMapper\\MappedObject\.$# in path /home/runner/work/object-mapper/object-mapper/src/Callbacks/BaseCallback.php is expected to occur 1 time, but occurred 2 times.
: (fn () => $instance->$method($data, $context))

Check failure on line 353 in src/Callbacks/BaseCallback.php

View workflow job for this annotation

GitHub Actions / Static analysis (ubuntu-latest, 8.4)

Variable method call on Orisai\ObjectMapper\MappedObject.
->bindTo($instance, $declaringClass->getName())();
// phpcs:enable
}

return $args->returnsValue ? $callbackOutput : $data;
Expand Down
25 changes: 17 additions & 8 deletions src/Processing/DefaultProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
use function array_map;
use function assert;
use function is_array;
use const PHP_VERSION_ID;

final class DefaultProcessor implements Processor
{
Expand Down Expand Up @@ -576,22 +577,30 @@ private function objectSet(MappedObject $object, ReflectionProperty $property, $
$declaringClass = $property->getDeclaringClass();
$name = $property->getName();

// phpcs:disable SlevomatCodingStandard.Functions.StaticClosure
(fn () => $object->$name = $value)
->bindTo($object, $declaringClass->getName())();
// phpcs:enable
if ($property->isPublic() && (PHP_VERSION_ID < 8_01_00 || !$property->isReadOnly())) {
$object->$name = $value;
} else {
// phpcs:disable SlevomatCodingStandard.Functions.StaticClosure
(fn () => $object->$name = $value)
->bindTo($object, $declaringClass->getName())();
// phpcs:enable
}
}

private function objectUnset(MappedObject $object, ReflectionProperty $property): void
{
$declaringClass = $property->getDeclaringClass();
$name = $property->getName();

// phpcs:disable SlevomatCodingStandard.Functions.StaticClosure
(function () use ($object, $name): void {
if ($property->isPublic() && (PHP_VERSION_ID < 8_01_00 || !$property->isReadOnly())) {
unset($object->$name);
})->bindTo($object, $declaringClass->getName())();
// phpcs:enable
} else {
// phpcs:disable SlevomatCodingStandard.Functions.StaticClosure
(function () use ($object, $name): void {
unset($object->$name);
})->bindTo($object, $declaringClass->getName())();
// phpcs:enable
}
}

}

0 comments on commit 62fcfac

Please sign in to comment.