public function instrument(TypeInfoInterface $type, InstrumentationInterface $instrumentation) { if (!$type->isClass()) { return; } $names = array_map('strtolower', $this->aspects); if (in_array(strtolower($type->getName()), $names)) { return; } $manager = $instrumentation->getTypeInfoManager(); // Aspects must not be target of advice: foreach ($type->getSupertypes($manager, true) as $supertype) { if (in_array(strtolower($supertype->getName()), $names)) { return; } } // $instrumentation->introduceInitializationCode('@header("K2-AOP: " . ' . var_export($type->getName(), true) . ', false);'); // $intercepted = false; // $advices = []; // foreach($this->getAdvisors(Advisor::TARGET_TYPE) as $advisor) // { // if($advisor->matches($type)) // { // $advices[] = $advisor->getAdvice(); // } // } // if(!empty($advices)) // { // $intercepted = true; // foreach($this->orderAdvices($advices) as $advice) // { // // Generate introduction code here... // } // } $intercepted = false; foreach ($this->collectMethods($type, $manager) as $method) { if ($this->interceptMethod($type, $method, $instrumentation)) { $intercepted = true; } } $interceptedFields = []; foreach ($this->collectFields($type, $manager) as $field) { if ($this->interceptField($type, $field, $instrumentation)) { $intercepted = true; $interceptedFields[] = $field; } } if ($intercepted) { $instrumentation->introduceInterface(InterceptedInterface::class); $instrumentation->introduceTrait(InterceptedTrait::class); if (!empty($interceptedFields)) { $instrumentation->introduceTrait(FieldInterceptionTrait::class); $fields = ''; $code = ''; $unsetFields = []; foreach ($interceptedFields as $field) { if ($field->isPublic()) { $fields .= 'public '; } elseif ($field->isProtected()) { $fields .= 'protected '; } else { $fields .= 'private '; } $fields .= '$____' . $field->getName() . '; '; $code .= '$this->____' . $field->getName(); $code .= ' = $this->'; $code .= $field->getName() . '; '; $unsetFields[] = $field->getName(); } if (!empty($unsetFields)) { $code .= 'unset(' . implode(', ', array_map(function ($name) { return '$this->' . $name; }, $unsetFields)) . ');'; } $instrumentation->introduceCode($fields); $instrumentation->introduceInitializationCode($code); } } }