1
0
mirror of https://github.com/danog/class-finder.git synced 2024-11-30 04:29:03 +01:00

Add support for functions

This commit is contained in:
Daniil Gentili 2020-10-13 09:11:09 +02:00
parent e6ab750844
commit ad3c854638
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
7 changed files with 42 additions and 21 deletions

View File

@ -1,7 +1,7 @@
ClassFinder ClassFinder
=========== ===========
A dead simple utility to identify classes, traits and interfaces in a given namespace. A dead simple utility to identify classes, traits, functions and interfaces in a given namespace.
This package is an improved implementation of an [answer on Stack Overflow](https://stackoverflow.com/a/40229665/3000068) This package is an improved implementation of an [answer on Stack Overflow](https://stackoverflow.com/a/40229665/3000068)
and provides additional features with less configuration required. and provides additional features with less configuration required.
@ -55,6 +55,7 @@ $classes = ClassFinder::getClassesInNamespace('TestApp1\Foo');
$classes = ClassFinder::getClassesInNamespace('TestApp1\Foo', ClassFinder::ALLOW_CLASSES); $classes = ClassFinder::getClassesInNamespace('TestApp1\Foo', ClassFinder::ALLOW_CLASSES);
$interfaces = ClassFinder::getClassesInNamespace('TestApp1\Foo', ClassFinder::ALLOW_INTERFACES); $interfaces = ClassFinder::getClassesInNamespace('TestApp1\Foo', ClassFinder::ALLOW_INTERFACES);
$traits = ClassFinder::getClassesInNamespace('TestApp1\Foo', ClassFinder::ALLOW_TRAITS); $traits = ClassFinder::getClassesInNamespace('TestApp1\Foo', ClassFinder::ALLOW_TRAITS);
$funcs = ClassFinder::getClassesInNamespace('TestApp1\Foo', ClassFinder::ALLOW_FUNCTIONS);
// You can combine any of the flags // You can combine any of the flags
$interfacesTraits = ClassFinder::getClassesInNamespace('TestApp1\Foo', ClassFinder::ALLOW_TRAITS | ClassFinder::ALLOW_INTERFACES); $interfacesTraits = ClassFinder::getClassesInNamespace('TestApp1\Foo', ClassFinder::ALLOW_TRAITS | ClassFinder::ALLOW_INTERFACES);
@ -80,6 +81,12 @@ var_dump($interfaces);
* ) * )
*/ */
var_dump($traits); var_dump($traits);
/**
* array(
* 'TestApp1\Foo\myFunc',
* )
*/
var_dump($funcs);
/** /**
* array( * array(
* 'TestApp1\Foo\BarInterface', * 'TestApp1\Foo\BarInterface',
@ -102,6 +109,7 @@ $classes = ClassFinder::getClassesInNamespace('TestApp1\Foo', ClassFinder::RECUR
$classes = ClassFinder::getClassesInNamespace('TestApp1\Foo', ClassFinder::RECURSIVE_MODE | ClassFinder::ALLOW_CLASSES); $classes = ClassFinder::getClassesInNamespace('TestApp1\Foo', ClassFinder::RECURSIVE_MODE | ClassFinder::ALLOW_CLASSES);
$interfaces = ClassFinder::getClassesInNamespace('TestApp1\Foo', ClassFinder::RECURSIVE_MODE | ClassFinder::ALLOW_INTERFACES); $interfaces = ClassFinder::getClassesInNamespace('TestApp1\Foo', ClassFinder::RECURSIVE_MODE | ClassFinder::ALLOW_INTERFACES);
$traits = ClassFinder::getClassesInNamespace('TestApp1\Foo', ClassFinder::RECURSIVE_MODE | ClassFinder::ALLOW_TRAITS); $traits = ClassFinder::getClassesInNamespace('TestApp1\Foo', ClassFinder::RECURSIVE_MODE | ClassFinder::ALLOW_TRAITS);
$funcs = ClassFinder::getClassesInNamespace('TestApp1\Foo', ClassFinder::RECURSIVE_MODE | ClassFinder::ALLOW_FUNCTIONS);
// You can combine any of the flags // You can combine any of the flags
@ -125,6 +133,7 @@ var_dump($classes);
// You get the idea :) // You get the idea :)
var_dump($interfaces); var_dump($interfaces);
var_dump($traits); var_dump($traits);
var_dump($funcs);
var_dump($classesTraits); var_dump($classesTraits);
``` ```

View File

@ -1,9 +1,8 @@
{ {
"name": "danog/class-finder", "name": "danog/class-finder",
"description": "Fork of haydenpierce/class-finder with support for traits and interfaces", "description": "Fork of haydenpierce/class-finder with support for traits, interfaces and functions",
"type": "library", "type": "library",
"license": "MIT", "license": "MIT",
"version": "0.4.3",
"authors": [ "authors": [
{ {
"name": "Hayden Pierce", "name": "Hayden Pierce",

View File

@ -16,6 +16,9 @@ class ClassFinder
const ALLOW_CLASSES = 4; const ALLOW_CLASSES = 4;
const ALLOW_INTERFACES = 8; const ALLOW_INTERFACES = 8;
const ALLOW_TRAITS = 16; const ALLOW_TRAITS = 16;
const ALLOW_FUNCTIONS = 32;
const ALLOW_ALL = 60;
const MODE_MASK = 3; const MODE_MASK = 3;

View File

@ -22,26 +22,30 @@ class ClassmapEntryFactory
{ {
// Composer will compile user declared mappings to autoload_classmap.php. So no additional work is needed // Composer will compile user declared mappings to autoload_classmap.php. So no additional work is needed
// to fetch user provided entries. // to fetch user provided entries.
$classmap = require($this->appConfig->getAppRoot() . 'vendor/composer/autoload_classmap.php'); $classmap = require($this->appConfig->getAppRoot().'vendor/composer/autoload_classmap.php');
$finalClassMap = array(); $finalClassMap = [];
foreach ($classmap as $potentialClass => $file) { foreach ($classmap as $potentialClass => $file) {
if ($allowAdditional & ClassFinder::ALLOW_CLASSES && class_exists($potentialClass) if (\function_exists($potentialClass)) {
|| ($allowAdditional & ClassFinder::ALLOW_INTERFACES && interface_exists($potentialClass)) if ($allowAdditional & ClassFinder::ALLOW_FUNCTIONS) {
|| ($allowAdditional & ClassFinder::ALLOW_TRAITS && trait_exists($potentialClass))) { $finalClassMap[$potentialClass] = $file;
}
} elseif ($allowAdditional & ClassFinder::ALLOW_CLASSES && \class_exists($potentialClass)
|| ($allowAdditional & ClassFinder::ALLOW_INTERFACES && \interface_exists($potentialClass))
|| ($allowAdditional & ClassFinder::ALLOW_TRAITS && \trait_exists($potentialClass))) {
$finalClassMap[$potentialClass] = $file; $finalClassMap[$potentialClass] = $file;
} }
} }
$classmap = $finalClassMap; $classmap = $finalClassMap;
// if classmap has no entries return empty array // if classmap has no entries return empty array
if(count($classmap) == 0) { if (\count($classmap) == 0) {
return array(); return [];
} }
$classmapKeys = array_keys($classmap); $classmapKeys = \array_keys($classmap);
return array_map(function($index) use ($classmapKeys){ return \array_map(function ($index) use ($classmapKeys) {
return new ClassmapEntry($classmapKeys[$index]); return new ClassmapEntry($classmapKeys[$index]);
}, range(0, count($classmap) - 1)); }, \range(0, \count($classmap) - 1));
} }
} }

View File

@ -21,7 +21,7 @@ class ClassmapFinder implements FinderInterface
*/ */
public function isNamespaceKnown($namespace) public function isNamespaceKnown($namespace)
{ {
$classmapEntries = $this->factory->getClassmapEntries(ClassFinder::ALLOW_CLASSES | ClassFinder::ALLOW_INTERFACES | ClassFinder::ALLOW_TRAITS); $classmapEntries = $this->factory->getClassmapEntries(ClassFinder::ALLOW_ALL);
foreach($classmapEntries as $classmapEntry) { foreach($classmapEntries as $classmapEntry) {
if ($classmapEntry->knowsNamespace($namespace)) { if ($classmapEntry->knowsNamespace($namespace)) {

View File

@ -28,7 +28,7 @@ class FilesEntry
*/ */
public function knowsNamespace($namespace) public function knowsNamespace($namespace)
{ {
$classes = $this->getClassesInFile(ClassFinder::ALLOW_CLASSES | ClassFinder::ALLOW_INTERFACES | ClassFinder::ALLOW_TRAITS); $classes = $this->getClassesInFile(ClassFinder::ALLOW_ALL);
foreach($classes as $class) { foreach($classes as $class) {
if (strpos($class, $namespace) !== false) { if (strpos($class, $namespace) !== false) {
@ -88,18 +88,21 @@ class FilesEntry
// get_declared_*() returns a bunch of classes|interfaces|traits that are built into PHP. So we need a control here. // get_declared_*() returns a bunch of classes|interfaces|traits that are built into PHP. So we need a control here.
list($initialInterfaces, list($initialInterfaces,
$initialClasses, $initialClasses,
$initialTraits $initialTraits,
) = $this->execReturn("var_export(array(get_declared_interfaces(), get_declared_classes(), get_declared_traits()));"); $initialFuncs
) = $this->execReturn("var_export(array(get_declared_interfaces(), get_declared_classes(), get_declared_traits(), get_defined_functions()['user']));");
// This brings in the new classes. so $classes here will include the PHP defaults and the newly defined classes // This brings in the new classes. so $classes here will include the PHP defaults and the newly defined classes
list($allInterfaces, list($allInterfaces,
$allClasses, $allClasses,
$allTraits $allTraits,
) = $this->execReturn("require_once '{$this->file}'; var_export(array(get_declared_interfaces(), get_declared_classes(), get_declared_traits()));"); $allFuncs
) = $this->execReturn("require_once '{$this->file}'; var_export(array(get_declared_interfaces(), get_declared_classes(), get_declared_traits(), get_defined_functions()['user']));");
$interfaces = array_diff($allInterfaces, $initialInterfaces); $interfaces = array_diff($allInterfaces, $initialInterfaces);
$classes = array_diff($allClasses, $initialClasses); $classes = array_diff($allClasses, $initialClasses);
$traits = array_diff($allTraits, $initialTraits); $traits = array_diff($allTraits, $initialTraits);
$funcs = array_diff($allFuncs, $initialFuncs);
$final = array(); $final = array();
if ($options & ClassFinder::ALLOW_CLASSES) { if ($options & ClassFinder::ALLOW_CLASSES) {
@ -111,6 +114,9 @@ class FilesEntry
if ($options & ClassFinder::ALLOW_TRAITS) { if ($options & ClassFinder::ALLOW_TRAITS) {
$final = array_merge($final, $traits); $final = array_merge($final, $traits);
} }
if ($options & ClassFinder::ALLOW_FUNCTIONS) {
$final = array_merge($final, $funcs);
}
return $final; return $final;
} }

View File

@ -203,7 +203,7 @@ class PSR4Namespace
if (function_exists($potentialClass)) { if (function_exists($potentialClass)) {
// For some reason calling class_exists() on a namespace'd function raises a Fatal Error (tested PHP 7.0.8) // For some reason calling class_exists() on a namespace'd function raises a Fatal Error (tested PHP 7.0.8)
// Example: DeepCopy\deep_copy // Example: DeepCopy\deep_copy
return false; return ($allowAdditional & ClassFinder::ALLOW_FUNCTIONS);
} else { } else {
return ($allowAdditional & ClassFinder::ALLOW_CLASSES && class_exists($potentialClass)) return ($allowAdditional & ClassFinder::ALLOW_CLASSES && class_exists($potentialClass))
|| ($allowAdditional & ClassFinder::ALLOW_INTERFACES && interface_exists($potentialClass)) || ($allowAdditional & ClassFinder::ALLOW_INTERFACES && interface_exists($potentialClass))
@ -247,7 +247,7 @@ class PSR4Namespace
if (function_exists($potentialClass)) { if (function_exists($potentialClass)) {
// For some reason calling class_exists() on a namespace'd function raises a Fatal Error (tested PHP 7.0.8) // For some reason calling class_exists() on a namespace'd function raises a Fatal Error (tested PHP 7.0.8)
// Example: DeepCopy\deep_copy // Example: DeepCopy\deep_copy
return false; return ($allowAdditional & ClassFinder::ALLOW_FUNCTIONS);
} else { } else {
return ($allowAdditional & ClassFinder::ALLOW_CLASSES && class_exists($potentialClass)) return ($allowAdditional & ClassFinder::ALLOW_CLASSES && class_exists($potentialClass))
|| ($allowAdditional & ClassFinder::ALLOW_INTERFACES && interface_exists($potentialClass)) || ($allowAdditional & ClassFinder::ALLOW_INTERFACES && interface_exists($potentialClass))