isInterface()) { $interfaces[] = $originalClass->getName(); } else { $classGenerator->setExtendedClass($originalClass->getName()); } $classGenerator->setImplementedInterfaces($interfaces); $classGenerator->addPropertyFromGenerator($valueHolder = new ValueHolderProperty($originalClass)); $classGenerator->addPropertyFromGenerator($prefixInterceptors = new MethodPrefixInterceptors()); $classGenerator->addPropertyFromGenerator($suffixInterceptors = new MethodSuffixInterceptors()); $classGenerator->addPropertyFromGenerator($publicProperties); array_map( static function (MethodGenerator $generatedMethod) use ($originalClass, $classGenerator): void { ClassGeneratorUtils::addMethodIfNotFinal($originalClass, $classGenerator, $generatedMethod); }, array_merge( array_map( $this->buildMethodInterceptor($prefixInterceptors, $suffixInterceptors, $valueHolder), ProxiedMethodsFilter::getProxiedMethods($originalClass) ), [ Constructor::generateMethod($originalClass, $valueHolder), new StaticProxyConstructor($originalClass, $valueHolder, $prefixInterceptors, $suffixInterceptors), new GetWrappedValueHolderValue($valueHolder), new SetMethodPrefixInterceptor($prefixInterceptors), new SetMethodSuffixInterceptor($suffixInterceptors), new MagicGet( $originalClass, $valueHolder, $prefixInterceptors, $suffixInterceptors, $publicProperties ), new MagicSet( $originalClass, $valueHolder, $prefixInterceptors, $suffixInterceptors, $publicProperties ), new MagicIsset( $originalClass, $valueHolder, $prefixInterceptors, $suffixInterceptors, $publicProperties ), new MagicUnset( $originalClass, $valueHolder, $prefixInterceptors, $suffixInterceptors, $publicProperties ), new MagicClone($originalClass, $valueHolder, $prefixInterceptors, $suffixInterceptors), new MagicSleep($originalClass, $valueHolder), new MagicWakeup($originalClass), ] ) ); } private function buildMethodInterceptor( MethodPrefixInterceptors $prefixes, MethodSuffixInterceptors $suffixes, ValueHolderProperty $valueHolder ): callable { return static function (ReflectionMethod $method) use ($prefixes, $suffixes, $valueHolder): InterceptedMethod { return InterceptedMethod::generateMethod( new MethodReflection($method->getDeclaringClass()->getName(), $method->getName()), $valueHolder, $prefixes, $suffixes ); }; } }