One Hat Cyber Team
Your IP:
216.73.216.101
Server IP:
198.54.114.155
Server:
Linux server71.web-hosting.com 4.18.0-513.18.1.lve.el8.x86_64 #1 SMP Thu Feb 22 12:55:50 UTC 2024 x86_64
Server Software:
LiteSpeed
PHP Version:
5.6.40
Create File
|
Create Folder
Execute
Dir :
~
/
proc
/
thread-self
/
root
/
proc
/
thread-self
/
cwd
/
View File Name :
TabCompletion.tar
Matcher/ClassNamesMatcher.php 0000644 00000004600 15112003470 0012166 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; /** * A class name tab completion Matcher. * * This matcher provides completion for all declared classes. * * @author Marc Garcia <markcial@gmail.com> */ class ClassNamesMatcher extends AbstractMatcher { /** * {@inheritdoc} */ public function getMatches(array $tokens, array $info = []): array { $class = $this->getNamespaceAndClass($tokens); if ($class !== '' && $class[0] === '\\') { $class = \substr($class, 1, \strlen($class)); } $quotedClass = \preg_quote($class); return \array_map( function ($className) use ($class) { // get the number of namespace separators $nsPos = \substr_count($class, '\\'); $pieces = \explode('\\', $className); // $methods = Mirror::get($class); return \implode('\\', \array_slice($pieces, $nsPos, \count($pieces))); }, \array_filter( \array_merge(\get_declared_classes(), \get_declared_interfaces()), function ($className) use ($quotedClass) { return AbstractMatcher::startsWith($quotedClass, $className); } ) ); } /** * {@inheritdoc} */ public function hasMatched(array $tokens): bool { $token = \array_pop($tokens); $prevToken = \array_pop($tokens); $ignoredTokens = [ self::T_INCLUDE, self::T_INCLUDE_ONCE, self::T_REQUIRE, self::T_REQUIRE_ONCE, ]; switch (true) { case self::hasToken([$ignoredTokens], $token): case self::hasToken([$ignoredTokens], $prevToken): case \is_string($token) && $token === '$': return false; case self::hasToken([self::T_NEW, self::T_OPEN_TAG, self::T_NS_SEPARATOR, self::T_STRING], $prevToken): case self::hasToken([self::T_NEW, self::T_OPEN_TAG, self::T_NS_SEPARATOR], $token): case self::hasToken([self::T_OPEN_TAG, self::T_VARIABLE], $token): case self::isOperator($token): return true; } return false; } } Matcher/ClassAttributesMatcher.php 0000644 00000004321 15112003470 0013251 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; /** * A class attribute tab completion Matcher. * * Given a namespace and class, this matcher provides completion for constants * and static properties. * * @author Marc Garcia <markcial@gmail.com> */ class ClassAttributesMatcher extends AbstractMatcher { /** * {@inheritdoc} */ public function getMatches(array $tokens, array $info = []): array { $input = $this->getInput($tokens); $firstToken = \array_pop($tokens); if (self::tokenIs($firstToken, self::T_STRING)) { // second token is the nekudotayim operator \array_pop($tokens); } $class = $this->getNamespaceAndClass($tokens); try { $reflection = new \ReflectionClass($class); } catch (\ReflectionException $re) { return []; } $vars = \array_merge( \array_map( function ($var) { return '$'.$var; }, \array_keys($reflection->getStaticProperties()) ), \array_keys($reflection->getConstants()) ); return \array_map( function ($name) use ($class) { $chunks = \explode('\\', $class); $className = \array_pop($chunks); return $className.'::'.$name; }, \array_filter( $vars, function ($var) use ($input) { return AbstractMatcher::startsWith($input, $var); } ) ); } /** * {@inheritdoc} */ public function hasMatched(array $tokens): bool { $token = \array_pop($tokens); $prevToken = \array_pop($tokens); switch (true) { case self::tokenIs($prevToken, self::T_DOUBLE_COLON) && self::tokenIs($token, self::T_STRING): case self::tokenIs($token, self::T_DOUBLE_COLON): return true; } return false; } } Matcher/FunctionsMatcher.php 0000644 00000002604 15112003470 0012107 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; /** * A function name tab completion Matcher. * * This matcher provides completion for all internal and user-defined functions. * * @author Marc Garcia <markcial@gmail.com> */ class FunctionsMatcher extends AbstractMatcher { /** * {@inheritdoc} */ public function getMatches(array $tokens, array $info = []): array { $func = $this->getInput($tokens); $functions = \get_defined_functions(); $allFunctions = \array_merge($functions['user'], $functions['internal']); return \array_filter($allFunctions, function ($function) use ($func) { return AbstractMatcher::startsWith($func, $function); }); } /** * {@inheritdoc} */ public function hasMatched(array $tokens): bool { $token = \array_pop($tokens); $prevToken = \array_pop($tokens); switch (true) { case self::tokenIs($prevToken, self::T_NEW): return false; case self::hasToken([self::T_OPEN_TAG, self::T_STRING], $token): case self::isOperator($token): return true; } return false; } } Matcher/ClassMethodsMatcher.php 0000644 00000004277 15112003470 0012540 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; /** * A class method tab completion Matcher. * * Given a namespace and class, this matcher provides completion for static * methods. * * @author Marc Garcia <markcial@gmail.com> */ class ClassMethodsMatcher extends AbstractMatcher { /** * {@inheritdoc} */ public function getMatches(array $tokens, array $info = []): array { $input = $this->getInput($tokens); $firstToken = \array_pop($tokens); if (self::tokenIs($firstToken, self::T_STRING)) { // second token is the nekudotayim operator \array_pop($tokens); } $class = $this->getNamespaceAndClass($tokens); try { $reflection = new \ReflectionClass($class); } catch (\ReflectionException $re) { return []; } if (self::needCompleteClass($tokens[1])) { $methods = $reflection->getMethods(); } else { $methods = $reflection->getMethods(\ReflectionMethod::IS_STATIC); } $methods = \array_map(function (\ReflectionMethod $method) { return $method->getName(); }, $methods); return \array_map( function ($name) use ($class) { $chunks = \explode('\\', $class); $className = \array_pop($chunks); return $className.'::'.$name; }, \array_filter($methods, function ($method) use ($input) { return AbstractMatcher::startsWith($input, $method); }) ); } /** * {@inheritdoc} */ public function hasMatched(array $tokens): bool { $token = \array_pop($tokens); $prevToken = \array_pop($tokens); switch (true) { case self::tokenIs($prevToken, self::T_DOUBLE_COLON) && self::tokenIs($token, self::T_STRING): case self::tokenIs($token, self::T_DOUBLE_COLON): return true; } return false; } } Matcher/VariablesMatcher.php 0000644 00000002355 15112003471 0012053 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; /** * A variable name tab completion Matcher. * * This matcher provides completion for variable names in the current Context. * * @author Marc Garcia <markcial@gmail.com> */ class VariablesMatcher extends AbstractContextAwareMatcher { /** * {@inheritdoc} */ public function getMatches(array $tokens, array $info = []): array { $var = \str_replace('$', '', $this->getInput($tokens)); return \array_filter(\array_keys($this->getVariables()), function ($variable) use ($var) { return AbstractMatcher::startsWith($var, $variable); }); } /** * {@inheritdoc} */ public function hasMatched(array $tokens): bool { $token = \array_pop($tokens); switch (true) { case self::hasToken([self::T_OPEN_TAG, self::T_VARIABLE], $token): case \is_string($token) && $token === '$': case self::isOperator($token): return true; } return false; } } Matcher/AbstractDefaultParametersMatcher.php 0000644 00000004026 15112003471 0015234 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; abstract class AbstractDefaultParametersMatcher extends AbstractContextAwareMatcher { /** * @param \ReflectionParameter[] $reflectionParameters * * @return array */ public function getDefaultParameterCompletion(array $reflectionParameters): array { $parametersProcessed = []; foreach ($reflectionParameters as $parameter) { if (!$parameter->isDefaultValueAvailable()) { return []; } $defaultValue = $this->valueToShortString($parameter->getDefaultValue()); $parametersProcessed[] = \sprintf('$%s = %s', $parameter->getName(), $defaultValue); } if (empty($parametersProcessed)) { return []; } return [\implode(', ', $parametersProcessed).')']; } /** * Takes in the default value of a parameter and turns it into a * string representation that fits inline. * This is not 100% true to the original (newlines are inlined, for example). * * @param mixed $value */ private function valueToShortString($value): string { if (!\is_array($value)) { return \json_encode($value); } $chunks = []; $chunksSequential = []; $allSequential = true; foreach ($value as $key => $item) { $allSequential = $allSequential && \is_numeric($key) && $key === \count($chunksSequential); $keyString = $this->valueToShortString($key); $itemString = $this->valueToShortString($item); $chunks[] = "{$keyString} => {$itemString}"; $chunksSequential[] = $itemString; } $chunksToImplode = $allSequential ? $chunksSequential : $chunks; return '['.\implode(', ', $chunksToImplode).']'; } } Matcher/AbstractMatcher.php 0000644 00000011506 15112003471 0011704 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; /** * Abstract tab completion Matcher. * * @author Marc Garcia <markcial@gmail.com> */ abstract class AbstractMatcher { /** Syntax types */ const CONSTANT_SYNTAX = '^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$'; const VAR_SYNTAX = '^\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$'; const MISC_OPERATORS = '+-*/^|&'; /** Token values */ const T_OPEN_TAG = 'T_OPEN_TAG'; const T_VARIABLE = 'T_VARIABLE'; const T_OBJECT_OPERATOR = 'T_OBJECT_OPERATOR'; const T_DOUBLE_COLON = 'T_DOUBLE_COLON'; const T_NEW = 'T_NEW'; const T_CLONE = 'T_CLONE'; const T_NS_SEPARATOR = 'T_NS_SEPARATOR'; const T_STRING = 'T_STRING'; const T_NAME_QUALIFIED = 'T_NAME_QUALIFIED'; const T_WHITESPACE = 'T_WHITESPACE'; const T_AND_EQUAL = 'T_AND_EQUAL'; const T_BOOLEAN_AND = 'T_BOOLEAN_AND'; const T_BOOLEAN_OR = 'T_BOOLEAN_OR'; const T_ENCAPSED_AND_WHITESPACE = 'T_ENCAPSED_AND_WHITESPACE'; const T_REQUIRE = 'T_REQUIRE'; const T_REQUIRE_ONCE = 'T_REQUIRE_ONCE'; const T_INCLUDE = 'T_INCLUDE'; const T_INCLUDE_ONCE = 'T_INCLUDE_ONCE'; /** * Check whether this matcher can provide completions for $tokens. * * @param array $tokens Tokenized readline input * * @return false */ public function hasMatched(array $tokens): bool { return false; } /** * Get current readline input word. * * @param array $tokens Tokenized readline input (see token_get_all) */ protected function getInput(array $tokens): string { $var = ''; $firstToken = \array_pop($tokens); if (self::tokenIs($firstToken, self::T_STRING)) { $var = $firstToken[1]; } return $var; } /** * Get current namespace and class (if any) from readline input. * * @param array $tokens Tokenized readline input (see token_get_all) */ protected function getNamespaceAndClass(array $tokens): string { $class = ''; while (self::hasToken( [self::T_NS_SEPARATOR, self::T_STRING, self::T_NAME_QUALIFIED], $token = \array_pop($tokens) )) { if (self::needCompleteClass($token)) { continue; } $class = $token[1].$class; } return $class; } /** * Provide tab completion matches for readline input. * * @param array $tokens information substracted with get_token_all * @param array $info readline_info object * * @return array The matches resulting from the query */ abstract public function getMatches(array $tokens, array $info = []): array; /** * Check whether $word starts with $prefix. * * @param string $prefix * @param string $word */ public static function startsWith(string $prefix, string $word): bool { return \preg_match(\sprintf('#^%s#', $prefix), $word); } /** * Check whether $token matches a given syntax pattern. * * @param mixed $token A PHP token (see token_get_all) * @param string $syntax A syntax pattern (default: variable pattern) */ public static function hasSyntax($token, string $syntax = self::VAR_SYNTAX): bool { if (!\is_array($token)) { return false; } $regexp = \sprintf('#%s#', $syntax); return (bool) \preg_match($regexp, $token[1]); } /** * Check whether $token type is $which. * * @param mixed $token A PHP token (see token_get_all) * @param string $which A PHP token type */ public static function tokenIs($token, string $which): bool { if (!\is_array($token)) { return false; } return \token_name($token[0]) === $which; } /** * Check whether $token is an operator. * * @param mixed $token A PHP token (see token_get_all) */ public static function isOperator($token): bool { if (!\is_string($token)) { return false; } return \strpos(self::MISC_OPERATORS, $token) !== false; } public static function needCompleteClass($token): bool { return \in_array($token[1], ['doc', 'ls', 'show']); } /** * Check whether $token type is present in $coll. * * @param array $coll A list of token types * @param mixed $token A PHP token (see token_get_all) */ public static function hasToken(array $coll, $token): bool { if (!\is_array($token)) { return false; } return \in_array(\token_name($token[0]), $coll); } } Matcher/KeywordsMatcher.php 0000644 00000004054 15112003471 0011750 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; /** * A PHP keyword tab completion Matcher. * * This matcher provides completion for all function-like PHP keywords. * * @author Marc Garcia <markcial@gmail.com> */ class KeywordsMatcher extends AbstractMatcher { protected $keywords = [ 'array', 'clone', 'declare', 'die', 'echo', 'empty', 'eval', 'exit', 'include', 'include_once', 'isset', 'list', 'print', 'require', 'require_once', 'unset', ]; protected $mandatoryStartKeywords = [ 'die', 'echo', 'print', 'unset', ]; /** * Get all (completable) PHP keywords. * * @return string[] */ public function getKeywords(): array { return $this->keywords; } /** * Check whether $keyword is a (completable) PHP keyword. * * @param string $keyword */ public function isKeyword(string $keyword): bool { return \in_array($keyword, $this->keywords); } /** * {@inheritdoc} */ public function getMatches(array $tokens, array $info = []): array { $input = $this->getInput($tokens); return \array_filter($this->keywords, function ($keyword) use ($input) { return AbstractMatcher::startsWith($input, $keyword); }); } /** * {@inheritdoc} */ public function hasMatched(array $tokens): bool { $token = \array_pop($tokens); $prevToken = \array_pop($tokens); switch (true) { case self::hasToken([self::T_OPEN_TAG, self::T_VARIABLE], $token): // case is_string($token) && $token === '$': case self::hasToken([self::T_OPEN_TAG, self::T_VARIABLE], $prevToken) && self::tokenIs($token, self::T_STRING): case self::isOperator($token): return true; } return false; } } Matcher/AbstractContextAwareMatcher.php 0000644 00000002472 15112003471 0014233 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; use Psy\Context; use Psy\ContextAware; /** * An abstract tab completion Matcher which implements ContextAware. * * The AutoCompleter service will inject a Context instance into all * ContextAware Matchers. * * @author Marc Garcia <markcial@gmail.com> */ abstract class AbstractContextAwareMatcher extends AbstractMatcher implements ContextAware { /** * Context instance (for ContextAware interface). * * @var Context */ protected $context; /** * ContextAware interface. * * @param Context $context */ public function setContext(Context $context) { $this->context = $context; } /** * Get a Context variable by name. * * @param string $var Variable name * * @return mixed */ protected function getVariable(string $var) { return $this->context->get($var); } /** * Get all variables in the current Context. * * @return array */ protected function getVariables(): array { return $this->context->getAll(); } } Matcher/MongoClientMatcher.php 0000644 00000003417 15112003471 0012361 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; /** * A MongoDB Client tab completion Matcher. * * This matcher provides completion for MongoClient database names. * * @author Marc Garcia <markcial@gmail.com> */ class MongoClientMatcher extends AbstractContextAwareMatcher { /** * {@inheritdoc} */ public function getMatches(array $tokens, array $info = []): array { $input = $this->getInput($tokens); $firstToken = \array_pop($tokens); if (self::tokenIs($firstToken, self::T_STRING)) { // second token is the object operator \array_pop($tokens); } $objectToken = \array_pop($tokens); $objectName = \str_replace('$', '', $objectToken[1]); $object = $this->getVariable($objectName); if (!$object instanceof \MongoClient) { return []; } $list = $object->listDBs(); return \array_filter( \array_map(function ($info) { return $info['name']; }, $list['databases']), function ($var) use ($input) { return AbstractMatcher::startsWith($input, $var); } ); } /** * {@inheritdoc} */ public function hasMatched(array $tokens): bool { $token = \array_pop($tokens); $prevToken = \array_pop($tokens); switch (true) { case self::tokenIs($token, self::T_OBJECT_OPERATOR): case self::tokenIs($prevToken, self::T_OBJECT_OPERATOR): return true; } return false; } } Matcher/ObjectAttributesMatcher.php 0000644 00000003622 15112003471 0013416 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; use InvalidArgumentException; /** * An object attribute tab completion Matcher. * * This matcher provides completion for properties of objects in the current * Context. * * @author Marc Garcia <markcial@gmail.com> */ class ObjectAttributesMatcher extends AbstractContextAwareMatcher { /** * {@inheritdoc} */ public function getMatches(array $tokens, array $info = []): array { $input = $this->getInput($tokens); $firstToken = \array_pop($tokens); if (self::tokenIs($firstToken, self::T_STRING)) { // second token is the object operator \array_pop($tokens); } $objectToken = \array_pop($tokens); if (!\is_array($objectToken)) { return []; } $objectName = \str_replace('$', '', $objectToken[1]); try { $object = $this->getVariable($objectName); } catch (InvalidArgumentException $e) { return []; } if (!\is_object($object)) { return []; } return \array_filter( \array_keys(\get_class_vars(\get_class($object))), function ($var) use ($input) { return AbstractMatcher::startsWith($input, $var); } ); } /** * {@inheritdoc} */ public function hasMatched(array $tokens): bool { $token = \array_pop($tokens); $prevToken = \array_pop($tokens); switch (true) { case self::tokenIs($token, self::T_OBJECT_OPERATOR): case self::tokenIs($prevToken, self::T_OBJECT_OPERATOR): return true; } return false; } } Matcher/MongoDatabaseMatcher.php 0000644 00000003224 15112003471 0012643 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; /** * A MongoDB tab completion Matcher. * * This matcher provides completion for Mongo collection names. * * @author Marc Garcia <markcial@gmail.com> */ class MongoDatabaseMatcher extends AbstractContextAwareMatcher { /** * {@inheritdoc} */ public function getMatches(array $tokens, array $info = []): array { $input = $this->getInput($tokens); $firstToken = \array_pop($tokens); if (self::tokenIs($firstToken, self::T_STRING)) { // second token is the object operator \array_pop($tokens); } $objectToken = \array_pop($tokens); $objectName = \str_replace('$', '', $objectToken[1]); $object = $this->getVariable($objectName); if (!$object instanceof \MongoDB) { return []; } return \array_filter( $object->getCollectionNames(), function ($var) use ($input) { return AbstractMatcher::startsWith($input, $var); } ); } /** * {@inheritdoc} */ public function hasMatched(array $tokens): bool { $token = \array_pop($tokens); $prevToken = \array_pop($tokens); switch (true) { case self::tokenIs($token, self::T_OBJECT_OPERATOR): case self::tokenIs($prevToken, self::T_OBJECT_OPERATOR): return true; } return false; } } Matcher/ObjectMethodDefaultParametersMatcher.php 0000644 00000003375 15112003471 0016046 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; class ObjectMethodDefaultParametersMatcher extends AbstractDefaultParametersMatcher { public function getMatches(array $tokens, array $info = []): array { $openBracket = \array_pop($tokens); $functionName = \array_pop($tokens); $methodOperator = \array_pop($tokens); $objectToken = \array_pop($tokens); if (!\is_array($objectToken)) { return []; } $objectName = \str_replace('$', '', $objectToken[1]); try { $object = $this->getVariable($objectName); $reflection = new \ReflectionObject($object); } catch (\InvalidArgumentException $e) { return []; } catch (\ReflectionException $e) { return []; } $methods = $reflection->getMethods(); foreach ($methods as $method) { if ($method->getName() === $functionName[1]) { return $this->getDefaultParameterCompletion($method->getParameters()); } } return []; } public function hasMatched(array $tokens): bool { $openBracket = \array_pop($tokens); if ($openBracket !== '(') { return false; } $functionName = \array_pop($tokens); if (!self::tokenIs($functionName, self::T_STRING)) { return false; } $operator = \array_pop($tokens); if (!self::tokenIs($operator, self::T_OBJECT_OPERATOR)) { return false; } return true; } } Matcher/error_log 0000644 00000014764 15112003471 0010052 0 ustar 00 [27-Nov-2025 04:21:54 UTC] PHP Fatal error: Uncaught Error: Class "Psy\TabCompletion\Matcher\AbstractContextAwareMatcher" not found in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/VariablesMatcher.php:21 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/VariablesMatcher.php on line 21 [27-Nov-2025 04:22:14 UTC] PHP Fatal error: Uncaught Error: Class "Psy\TabCompletion\Matcher\AbstractMatcher" not found in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/ClassNamesMatcher.php:21 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/ClassNamesMatcher.php on line 21 [27-Nov-2025 04:23:36 UTC] PHP Fatal error: Uncaught Error: Class "Psy\TabCompletion\Matcher\AbstractMatcher" not found in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractContextAwareMatcher.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractContextAwareMatcher.php on line 25 [27-Nov-2025 04:24:16 UTC] PHP Fatal error: Uncaught Error: Class "Psy\TabCompletion\Matcher\AbstractContextAwareMatcher" not found in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractDefaultParametersMatcher.php:14 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractDefaultParametersMatcher.php on line 14 [27-Nov-2025 04:25:18 UTC] PHP Fatal error: Uncaught Error: Class "Psy\TabCompletion\Matcher\AbstractMatcher" not found in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/ClassAttributesMatcher.php:22 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/ClassAttributesMatcher.php on line 22 [27-Nov-2025 05:51:25 UTC] PHP Fatal error: Uncaught Error: Class "Psy\TabCompletion\Matcher\AbstractMatcher" not found in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/KeywordsMatcher.php:21 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/KeywordsMatcher.php on line 21 [27-Nov-2025 05:52:04 UTC] PHP Fatal error: Uncaught Error: Class "Psy\TabCompletion\Matcher\AbstractDefaultParametersMatcher" not found in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodDefaultParametersMatcher.php:14 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodDefaultParametersMatcher.php on line 14 [27-Nov-2025 05:58:16 UTC] PHP Fatal error: Uncaught Error: Class "Psy\TabCompletion\Matcher\AbstractContextAwareMatcher" not found in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/MongoClientMatcher.php:21 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/MongoClientMatcher.php on line 21 [27-Nov-2025 05:59:22 UTC] PHP Fatal error: Uncaught Error: Class "Psy\TabCompletion\Matcher\AbstractContextAwareMatcher" not found in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectAttributesMatcher.php:24 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectAttributesMatcher.php on line 24 [27-Nov-2025 07:03:38 UTC] PHP Fatal error: Uncaught Error: Class "Psy\TabCompletion\Matcher\AbstractMatcher" not found in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionsMatcher.php:21 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionsMatcher.php on line 21 [27-Nov-2025 07:05:01 UTC] PHP Fatal error: Uncaught Error: Class "Psy\TabCompletion\Matcher\AbstractDefaultParametersMatcher" not found in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionDefaultParametersMatcher.php:14 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionDefaultParametersMatcher.php on line 14 [27-Nov-2025 07:05:08 UTC] PHP Fatal error: Uncaught Error: Class "Psy\TabCompletion\Matcher\AbstractMatcher" not found in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/ConstantsMatcher.php:21 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/ConstantsMatcher.php on line 21 [27-Nov-2025 07:06:03 UTC] PHP Fatal error: Uncaught Error: Class "Psy\TabCompletion\Matcher\AbstractMatcher" not found in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/CommandsMatcher.php:24 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/CommandsMatcher.php on line 24 [27-Nov-2025 07:06:24 UTC] PHP Fatal error: Uncaught Error: Class "Psy\TabCompletion\Matcher\AbstractDefaultParametersMatcher" not found in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodDefaultParametersMatcher.php:14 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodDefaultParametersMatcher.php on line 14 [27-Nov-2025 07:07:12 UTC] PHP Fatal error: Uncaught Error: Class "Psy\TabCompletion\Matcher\AbstractContextAwareMatcher" not found in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/MongoDatabaseMatcher.php:21 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/MongoDatabaseMatcher.php on line 21 [27-Nov-2025 07:22:19 UTC] PHP Fatal error: Uncaught Error: Class "Psy\TabCompletion\Matcher\AbstractMatcher" not found in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodsMatcher.php:22 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodsMatcher.php on line 22 [27-Nov-2025 07:22:22 UTC] PHP Fatal error: Uncaught Error: Class "Psy\TabCompletion\Matcher\AbstractContextAwareMatcher" not found in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodsMatcher.php:24 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodsMatcher.php on line 24 Matcher/ConstantsMatcher.php 0000644 00000002515 15112003471 0012115 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; /** * A constant name tab completion Matcher. * * This matcher provides completion for all defined constants. * * @author Marc Garcia <markcial@gmail.com> */ class ConstantsMatcher extends AbstractMatcher { /** * {@inheritdoc} */ public function getMatches(array $tokens, array $info = []): array { $const = $this->getInput($tokens); return \array_filter(\array_keys(\get_defined_constants()), function ($constant) use ($const) { return AbstractMatcher::startsWith($const, $constant); }); } /** * {@inheritdoc} */ public function hasMatched(array $tokens): bool { $token = \array_pop($tokens); $prevToken = \array_pop($tokens); switch (true) { case self::tokenIs($prevToken, self::T_NEW): case self::tokenIs($prevToken, self::T_NS_SEPARATOR): return false; case self::hasToken([self::T_OPEN_TAG, self::T_STRING], $token): case self::isOperator($token): return true; } return false; } } Matcher/ClassMethodDefaultParametersMatcher.php 0000644 00000003155 15112003471 0015701 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; class ClassMethodDefaultParametersMatcher extends AbstractDefaultParametersMatcher { public function getMatches(array $tokens, array $info = []): array { $openBracket = \array_pop($tokens); $functionName = \array_pop($tokens); $methodOperator = \array_pop($tokens); $class = $this->getNamespaceAndClass($tokens); try { $reflection = new \ReflectionClass($class); } catch (\ReflectionException $e) { // In this case the class apparently does not exist, so we can do nothing return []; } $methods = $reflection->getMethods(\ReflectionMethod::IS_STATIC); foreach ($methods as $method) { if ($method->getName() === $functionName[1]) { return $this->getDefaultParameterCompletion($method->getParameters()); } } return []; } public function hasMatched(array $tokens): bool { $openBracket = \array_pop($tokens); if ($openBracket !== '(') { return false; } $functionName = \array_pop($tokens); if (!self::tokenIs($functionName, self::T_STRING)) { return false; } $operator = \array_pop($tokens); if (!self::tokenIs($operator, self::T_DOUBLE_COLON)) { return false; } return true; } } Matcher/CommandsMatcher.php 0000644 00000004706 15112003472 0011707 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; use Psy\Command\Command; /** * A Psy Command tab completion Matcher. * * This matcher provides completion for all registered Psy Command names and * aliases. * * @author Marc Garcia <markcial@gmail.com> */ class CommandsMatcher extends AbstractMatcher { /** @var string[] */ protected $commands = []; /** * CommandsMatcher constructor. * * @param Command[] $commands */ public function __construct(array $commands) { $this->setCommands($commands); } /** * Set Commands for completion. * * @param Command[] $commands */ public function setCommands(array $commands) { $names = []; foreach ($commands as $command) { $names = \array_merge([$command->getName()], $names); $names = \array_merge($command->getAliases(), $names); } $this->commands = $names; } /** * Check whether a command $name is defined. * * @param string $name */ protected function isCommand(string $name): bool { return \in_array($name, $this->commands); } /** * Check whether input matches a defined command. * * @param string $name */ protected function matchCommand(string $name): bool { foreach ($this->commands as $cmd) { if ($this->startsWith($name, $cmd)) { return true; } } return false; } /** * {@inheritdoc} */ public function getMatches(array $tokens, array $info = []): array { $input = $this->getInput($tokens); return \array_filter($this->commands, function ($command) use ($input) { return AbstractMatcher::startsWith($input, $command); }); } /** * {@inheritdoc} */ public function hasMatched(array $tokens): bool { /* $openTag */ \array_shift($tokens); $command = \array_shift($tokens); switch (true) { case self::tokenIs($command, self::T_STRING) && !$this->isCommand($command[1]) && $this->matchCommand($command[1]) && empty($tokens): return true; } return false; } } Matcher/FunctionDefaultParametersMatcher.php 0000644 00000002314 15112003472 0015255 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; class FunctionDefaultParametersMatcher extends AbstractDefaultParametersMatcher { public function getMatches(array $tokens, array $info = []): array { \array_pop($tokens); // open bracket $functionName = \array_pop($tokens); try { $reflection = new \ReflectionFunction($functionName[1]); } catch (\ReflectionException $e) { return []; } $parameters = $reflection->getParameters(); return $this->getDefaultParameterCompletion($parameters); } public function hasMatched(array $tokens): bool { $openBracket = \array_pop($tokens); if ($openBracket !== '(') { return false; } $functionName = \array_pop($tokens); if (!self::tokenIs($functionName, self::T_STRING)) { return false; } if (!\function_exists($functionName[1])) { return false; } return true; } } Matcher/ObjectMethodsMatcher.php 0000644 00000004040 15112003472 0012667 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion\Matcher; use InvalidArgumentException; /** * An object method tab completion Matcher. * * This matcher provides completion for methods of objects in the current * Context. * * @author Marc Garcia <markcial@gmail.com> */ class ObjectMethodsMatcher extends AbstractContextAwareMatcher { /** * {@inheritdoc} */ public function getMatches(array $tokens, array $info = []): array { $input = $this->getInput($tokens); $firstToken = \array_pop($tokens); if (self::tokenIs($firstToken, self::T_STRING)) { // second token is the object operator \array_pop($tokens); } $objectToken = \array_pop($tokens); if (!\is_array($objectToken)) { return []; } $objectName = \str_replace('$', '', $objectToken[1]); try { $object = $this->getVariable($objectName); } catch (InvalidArgumentException $e) { return []; } if (!\is_object($object)) { return []; } return \array_filter( \get_class_methods($object), function ($var) use ($input) { return AbstractMatcher::startsWith($input, $var) && // also check that we do not suggest invoking a super method(__construct, __wakeup, …) !AbstractMatcher::startsWith('__', $var); } ); } /** * {@inheritdoc} */ public function hasMatched(array $tokens): bool { $token = \array_pop($tokens); $prevToken = \array_pop($tokens); switch (true) { case self::tokenIs($token, self::T_OBJECT_OPERATOR): case self::tokenIs($prevToken, self::T_OBJECT_OPERATOR): return true; } return false; } } AutoCompleter.php 0000644 00000005526 15112003472 0010043 0 ustar 00 <?php /* * This file is part of Psy Shell. * * (c) 2012-2023 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\TabCompletion; use Psy\TabCompletion\Matcher\AbstractMatcher; /** * A readline tab completion service. * * @author Marc Garcia <markcial@gmail.com> */ class AutoCompleter { /** @var Matcher\AbstractMatcher[] */ protected $matchers; /** * Register a tab completion Matcher. * * @param AbstractMatcher $matcher */ public function addMatcher(AbstractMatcher $matcher) { $this->matchers[] = $matcher; } /** * Activate readline tab completion. */ public function activate() { \readline_completion_function([&$this, 'callback']); } /** * Handle readline completion. * * @param string $input Readline current word * @param int $index Current word index * @param array $info readline_info() data * * @return array */ public function processCallback(string $input, int $index, array $info = []): array { // Some (Windows?) systems provide incomplete `readline_info`, so let's // try to work around it. $line = $info['line_buffer']; if (isset($info['end'])) { $line = \substr($line, 0, $info['end']); } if ($line === '' && $input !== '') { $line = $input; } $tokens = \token_get_all('<?php '.$line); // remove whitespaces $tokens = \array_filter($tokens, function ($token) { return !AbstractMatcher::tokenIs($token, AbstractMatcher::T_WHITESPACE); }); // reset index from 0 to remove missing index number $tokens = \array_values($tokens); $matches = []; foreach ($this->matchers as $matcher) { if ($matcher->hasMatched($tokens)) { $matches = \array_merge($matcher->getMatches($tokens), $matches); } } $matches = \array_unique($matches); return !empty($matches) ? $matches : ['']; } /** * The readline_completion_function callback handler. * * @see processCallback * * @param string $input * @param int $index * * @return array */ public function callback(string $input, int $index): array { return $this->processCallback($input, $index, \readline_info()); } /** * Remove readline callback handler on destruct. */ public function __destruct() { // PHP didn't implement the whole readline API when they first switched // to libedit. And they still haven't. if (\function_exists('readline_callback_handler_remove')) { \readline_callback_handler_remove(); } } }