/**
  * @param $source   Reflection_Source the PHP source file object
  * @param $compiler PHP\Compiler the main compiler
  * @return boolean true if compilation process did something, else false
  */
 public function compile(Reflection_Source $source, PHP\Compiler $compiler = null)
 {
     $compiled = false;
     foreach ($source->getClasses() as $class) {
         // replace extends with the built replacement class
         if (!Builder::isBuilt($class->name)) {
             $parent_class_name = $class->getParentName();
             if ($parent_class_name) {
                 $replacement_class_name = Builder::className($parent_class_name);
                 if ($replacement_class_name != $parent_class_name) {
                     $class_exists = class_exists($replacement_class_name, false);
                     if ($class_exists && is_a($replacement_class_name, $parent_class_name) || !$class_exists && Reflection_Source::of($replacement_class_name)->getClass($replacement_class_name)->isA($class->name)) {
                         $replacement_class_name = $parent_class_name;
                     }
                 }
                 if (is_array($replacement_class_name)) {
                     trigger_error("Replacement classes should all be compiled", E_USER_ERROR);
                     $compiler->addSource($source);
                 } elseif ($replacement_class_name !== $parent_class_name && Builder::isBuilt($replacement_class_name)) {
                     $extended = null;
                     $buffer = $source->getSource();
                     $short_class_name = Namespaces::shortClassName($class->name);
                     $buffer = preg_replace_callback('%(\\s+class\\s+' . $short_class_name . '\\s+extends\\s+)([\\\\\\w]+)(\\s+)%', function ($match) use(&$extended, $replacement_class_name) {
                         $extended = $match[2];
                         return $match[1] . BS . $replacement_class_name . $match[3];
                     }, $buffer);
                     if ($extended) {
                         $buffer = preg_replace_callback('%(\\n\\s+\\*\\s+@link\\s+)(' . str_replace(BS, BS . BS, $extended) . ')(\\s+)%', function ($match) use($replacement_class_name) {
                             return $match[1] . BS . $replacement_class_name . $match[3];
                         }, $buffer);
                     }
                     $source->setSource($buffer);
                     $compiled = true;
                 }
             }
         }
     }
     return $compiled;
 }
Example #2
0
 /**
  * @param $sources Reflection_Source[]
  * @return Reflection_Source[] added sources list
  */
 public function moreSourcesToCompile(&$sources)
 {
     $added = [];
     // search into dependencies : used classes
     /** @var $search Dependency */
     $search = Search_Object::create(Dependency::class);
     $search->type = Dependency::T_USE;
     foreach ($sources as $source) {
         foreach ($source->getClasses() as $class) {
             if ($class->type === T_TRAIT) {
                 $search->dependency_name = $class->name;
                 foreach (Dao::search($search, Dependency::class) as $dependency) {
                     while ($dependency && Builder::isBuilt($dependency->class_name)) {
                         $search_built_parent = Search_Object::create(Dependency::class);
                         $search_built_parent->class_name = $dependency->class_name;
                         $search_built_parent->type = Dependency::T_EXTENDS;
                         $dependency = Dao::searchOne($search_built_parent);
                         if (!$dependency) {
                             trigger_error('Not parent class for built class ' . $search_built_parent->class_name, E_USER_ERROR);
                         }
                         $search_built_parent->class_name = $dependency->dependency_name;
                         $search_built_parent->type = Dependency::T_DECLARATION;
                         $dependency = Dao::searchOne($search_built_parent);
                         if (!$dependency) {
                             trigger_error('Not declaration dependency for class ' . $search_built_parent->class_name, E_USER_ERROR);
                         }
                     }
                     /** @var $dependency Dependency */
                     if (!isset($sources[$dependency->file_name])) {
                         $source = new Reflection_Source($dependency->file_name);
                         $sources[$dependency->file_name] = $source;
                         $added[$dependency->file_name] = $source;
                     }
                 }
             }
         }
     }
     // search into dependencies : registered methods
     foreach ($sources as $source) {
         $search->file_name = $source->file_name;
         $search->dependency_name = Registerable::class;
         $search->type = Dependency::T_IMPLEMENTS;
         if (Dao::searchOne($search, Dependency::class)) {
             unset($search->dependency_name);
             $search->type = Dependency::T_CLASS;
             foreach (Dao::search($search, Dependency::class) as $dependency) {
                 $source = Reflection_Source::of($dependency->dependency_name);
                 if (!isset($sources[$source->file_name])) {
                     $sources[$source->file_name] = $source;
                     $added[$source->file_name] = $source;
                 }
             }
         }
     }
     // classes that are already into $sources
     $already = [];
     foreach ($sources as $source) {
         foreach ($source->getClasses() as $class) {
             $already[$class->name] = true;
         }
     }
     // search into advices and add sources that have sources to compile as advice
     foreach ($this->weaver->getJoinpoints() as $class_name => $joinpoint) {
         if (!isset($already[$class_name])) {
             foreach ($joinpoint as $advices) {
                 foreach ($advices as $advice) {
                     if (is_array($advice = $advice[1])) {
                         $advice_class = $advice[0];
                         if (is_object($advice_class)) {
                             $advice_class = get_class($advice_class);
                         }
                         if (isset($already[$advice_class])) {
                             $source = Reflection_Source::of($class_name);
                             /*
                             if ($source->file_name && !$source->isInternal() && !is_file($source->file_name)) {
                             	$applicant_source = Reflection_Source::of($advice_class);
                             	if (
                             		!$source->searchFile($class_name, array_keys($applicant_source->getRequires()))
                             	) {
                             		trigger_error(
                             			'Reflection_Source file not found for class ' . $class_name, E_USER_ERROR
                             		);
                             	}
                             }
                             */
                             if ($source->getClass($class_name)) {
                                 $sources[$source->file_name] = $source;
                                 $added[$source->file_name] = $source;
                                 $already[$class_name] = true;
                             } else {
                                 trigger_error('No class ' . $class_name . ' into file ' . $source->file_name, E_USER_ERROR);
                             }
                         }
                     }
                 }
             }
         }
     }
     return $added;
 }
Example #3
0
 /**
  * @param $class_name string
  * @return Reflection_Class
  */
 public static function of($class_name)
 {
     return Reflection_Source::of($class_name)->getClass($class_name);
 }