/** * @param $source Reflection_Source */ public function onCompileSource(Reflection_Source $source) { Dao::begin(); foreach ($source->getClasses() as $class) { /** @var $log Compiler_Log */ $log = Builder::create(Compiler_Log::class); $log->class_name = $class->getName(); $log->date_time = Date_Time::now(); Dao::write($log); $this->log_flag = true; } Dao::commit(); }
/** * Compile built classes * * @param $source Reflection_Source * @param $compiler PHP\Compiler * @return boolean */ public function compile(Reflection_Source $source, PHP\Compiler $compiler = null) { $builder = Builder::current(); $builder->build = false; $compiled = false; foreach ($source->getClasses() as $class) { $replacement = $builder->getComposition($class->name); if (is_array($replacement)) { foreach (Class_Builder::build($class->name, $replacement, true) as $built_source) { $compiler->addSource((new Reflection_Source())->setSource('<?php' . LF . $built_source)); $compiled = true; } } } $builder->build = true; return $compiled; }
/** * @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; }
/** * @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; }
/** * Gets a Reflection_Source knowing its class _name. * Uses sources cache, or router's getClassFilename() and fill-in cache. * * @param $class_name string * @return Reflection_Source */ public function getClassFilename($class_name) { if (isset($this->sources_cache[$class_name])) { return $this->sources_cache[$class_name]; } else { /** @var $router Router */ $router = Session::current()->plugins->get(Router::class); if (Builder::isBuilt($class_name)) { $file_name = $this->getCacheDir() . SL . str_replace(SL, '-', Names::classToPath($class_name)); } else { $file_name = $router->getClassFilename($class_name); } $source = new Reflection_Source($file_name, $this, $class_name); foreach (array_keys($source->getClasses()) as $class_name) { $this->sources_cache[$class_name] = $source; if (count($this->sources_cache) > self::MAX_OPENED_SOURCES) { $source->free(self::SOURCES_FREE); } } return $this->sources_cache[$class_name]; } }
/** * Uses the file name getter to get a Reflection_Class class object (and linked source) * for a class name. * Use this to get a class from outside current source. * * @param $class_name string * @return Reflection_Class */ public function getOutsideClass($class_name) { if (isset($this->file_name_getter)) { $file_name = $this->file_name_getter->getClassFilename($class_name); $source = is_string($file_name) ? new Reflection_Source($file_name, $this->file_name_getter) : $file_name; } else { $filename = (new ReflectionClass($class_name))->getFileName(); $source = new Reflection_Source($filename, null, $filename ? null : $class_name); } return $source->getClass($class_name); }
/** * @param $class_name string * @return Reflection_Class */ public static function of($class_name) { return Reflection_Source::of($class_name)->getClass($class_name); }
/** * Compile source file into its class path * * @param $source Reflection_Source * @param $compiler Compiler * @return boolean false as this compilation does not modify the class source */ public function compile(Reflection_Source $source, Compiler $compiler = null) { foreach ($source->getClasses() as $class) { // class name to file path if (!isset($this->class_paths[$class->name]) || $this->class_paths[$class->name] !== $source->file_name) { $this->class_paths[$class->name] = $source->file_name; $this->changes = true; } // set class name to class name $set_class_name = $class->getSetClassName(); if (!isset($this->element_class_names[$set_class_name]) || $this->element_class_names[$set_class_name] !== $class->name) { $this->element_class_names[$set_class_name] = $class->name; $this->changes = true; } /* // short class name to class name $short_class_name = Namespaces::shortClassName($class->name); if ( !isset($this->full_class_names[$short_class_name]) || ($this->full_class_names[$short_class_name] !== $class->name) ) { $this->full_class_names[$short_class_name] = $class->name; $this->changes = true; } */ /* // set short class name to set class name $short_class_name = Namespaces::shortClassName($set_class_name); if ( !isset($this->full_class_names[$short_class_name]) || ($this->full_class_names[$short_class_name] !== $set_class_name) ) { $this->full_class_names[$short_class_name] = $set_class_name; $this->changes = true; } */ } return false; }