protected function buildConstructor(TypeInfoInterface $type, InstrumentationInterface $instrumentation) { $methods = $type->getMethods(); if ($type->hasMethod('__construct')) { // Instance creation checker... $code = 'if(static::$K2TypeName == __CLASS__) { '; $code .= $instrumentation->getInitializationCode(); $code .= ' }'; return $instrumentation->appendMethodCode($type->getMethod('__construct'), $code); } $con = NULL; foreach ($type->getSupertypes($instrumentation->getTypeInfoManager(), true) as $supertype) { if ($supertype->isClass() && $supertype->hasMethod('__construct')) { $con = $supertype->getMethod('__construct'); if ($con->isAbstract()) { continue; } if ($con->isFinal()) { throw new \RuntimeException(sprintf('Unable to compile initializer into type with inherited final constructor: %s', $type->getName())); } break; } } // No inherited constructor found, introduce standard constructor: if ($con === NULL) { if (empty($methods['__construct'])) { $code = 'public function __construct() { '; $code .= 'if(static::$K2TypeName == __CLASS__) { '; $code .= $instrumentation->getInitializationCode(); $code .= ' }'; $code .= '}'; return $instrumentation->introduceCode($code); } } // Inherited constructor found, enhance it by overloading: $code = $instrumentation->buildMethodSignature($con) . ' { '; $code .= 'if(func_num_args() <= ' . count($con->getParameters()) . ') { '; $code .= 'parent::__construct('; foreach ($con->getParameters() as $i => $param) { if ($i != 0) { $code .= ', '; } $code .= '$' . $param->getName(); } $code .= '); } else { '; $code .= 'forward_static_call_array([\'parent\', __FUNCTION__], func_get_args());'; $code .= ' } '; $code .= 'if(static::$K2TypeName == __CLASS__) { '; $code .= $instrumentation->getInitializationCode(); $code .= ' }'; $code .= ' }'; $instrumentation->introduceCode($code); }