first commit

This commit is contained in:
Sampanna Rimal
2024-08-27 17:48:06 +05:45
commit 53c0140f58
10839 changed files with 1125847 additions and 0 deletions

View File

@ -0,0 +1,41 @@
<?php
/*
Copyright (c) 2009 hamcrest.org
*/
class FactoryCall
{
/**
* Hamcrest standard is two spaces for each level of indentation.
*
* @var string
*/
const INDENT = ' ';
/**
* @var FactoryMethod
*/
private $method;
/**
* @var string
*/
private $name;
public function __construct(FactoryMethod $method, $name)
{
$this->method = $method;
$this->name = $name;
}
public function getMethod()
{
return $this->method;
}
public function getName()
{
return $this->name;
}
}

View File

@ -0,0 +1,71 @@
<?php
/*
Copyright (c) 2009 hamcrest.org
*/
class FactoryClass
{
/**
* @var string
*/
private $file;
/**
* @var ReflectionClass
*/
private $reflector;
/**
* @var array
*/
private $methods;
public function __construct($file, ReflectionClass $class)
{
$this->file = $file;
$this->reflector = $class;
$this->extractFactoryMethods();
}
public function extractFactoryMethods()
{
$this->methods = array();
foreach ($this->getPublicStaticMethods() as $method) {
if ($method->isFactory()) {
$this->methods[] = $method;
}
}
}
public function getPublicStaticMethods()
{
$methods = array();
foreach ($this->reflector->getMethods(ReflectionMethod::IS_STATIC) as $method) {
if ($method->isPublic() && $method->getDeclaringClass() == $this->reflector) {
$methods[] = new FactoryMethod($this, $method);
}
}
return $methods;
}
public function getFile()
{
return $this->file;
}
public function getName()
{
return $this->reflector->name;
}
public function isFactory()
{
return !empty($this->methods);
}
public function getMethods()
{
return $this->methods;
}
}

View File

@ -0,0 +1,121 @@
<?php
/*
Copyright (c) 2009 hamcrest.org
*/
abstract class FactoryFile
{
/**
* Hamcrest standard is two spaces for each level of indentation.
*
* @var string
*/
const INDENT = ' ';
private $indent;
private $file;
private $code;
public function __construct($file, $indent)
{
$this->file = $file;
$this->indent = $indent;
}
abstract public function addCall(FactoryCall $call);
abstract public function build();
public function addFileHeader()
{
$this->code = '';
$this->addPart('file_header');
}
public function addPart($name)
{
$this->addCode($this->readPart($name));
}
public function addCode($code)
{
$this->code .= $code;
}
public function readPart($name)
{
return file_get_contents(__DIR__ . "/parts/$name.txt");
}
public function generateFactoryCall(FactoryCall $call)
{
$method = $call->getMethod();
$code = $method->getComment($this->indent) . "\n";
$code .= $this->generateDeclaration($call->getName(), $method);
$code .= $this->generateCall($method);
$code .= $this->generateClosing();
return $code;
}
public function generateDeclaration($name, FactoryMethod $method)
{
$code = $this->indent . $this->getDeclarationModifiers()
. 'function ' . $name . '('
. $this->generateDeclarationArguments($method)
. ')' . "\n" . $this->indent . '{' . "\n";
return $code;
}
public function getDeclarationModifiers()
{
return '';
}
public function generateDeclarationArguments(FactoryMethod $method)
{
if ($method->acceptsVariableArguments()) {
return '/* args... */';
} else {
return $method->getParameterDeclarations();
}
}
public function generateImport(FactoryMethod $method)
{
return $this->indent . self::INDENT . "require_once '" . $method->getClass()->getFile() . "';" . "\n";
}
public function generateCall(FactoryMethod $method)
{
$code = '';
if ($method->acceptsVariableArguments()) {
$code .= $this->indent . self::INDENT . '$args = func_get_args();' . "\n";
}
$code .= $this->indent . self::INDENT . 'return ';
if ($method->acceptsVariableArguments()) {
$code .= 'call_user_func_array(array(\''
. '\\' . $method->getClassName() . '\', \''
. $method->getName() . '\'), $args);' . "\n";
} else {
$code .= '\\' . $method->getClassName() . '::'
. $method->getName() . '('
. $method->getParameterInvocations() . ');' . "\n";
}
return $code;
}
public function generateClosing()
{
return $this->indent . '}' . "\n";
}
public function write()
{
file_put_contents($this->file, $this->code);
}
}

View File

@ -0,0 +1,124 @@
<?php
/*
Copyright (c) 2009 hamcrest.org
*/
/**
* Controls the process of extracting @factory doctags
* and generating factory method files.
*
* Uses File_Iterator to scan for PHP files.
*/
class FactoryGenerator
{
/**
* Path to the Hamcrest PHP files to process.
*
* @var string
*/
private $path;
/**
* @var array of FactoryFile
*/
private $factoryFiles;
public function __construct($path)
{
$this->path = $path;
$this->factoryFiles = array();
}
public function addFactoryFile(FactoryFile $factoryFile)
{
$this->factoryFiles[] = $factoryFile;
}
public function generate()
{
$classes = $this->getClassesWithFactoryMethods();
foreach ($classes as $class) {
foreach ($class->getMethods() as $method) {
foreach ($method->getCalls() as $call) {
foreach ($this->factoryFiles as $file) {
$file->addCall($call);
}
}
}
}
}
public function write()
{
foreach ($this->factoryFiles as $file) {
$file->build();
$file->write();
}
}
public function getClassesWithFactoryMethods()
{
$classes = array();
$files = $this->getSortedFiles();
foreach ($files as $file) {
$class = $this->getFactoryClass($file);
if ($class !== null) {
$classes[] = $class;
}
}
return $classes;
}
public function getSortedFiles()
{
$iter = $this->getFileIterator();
$files = array();
foreach ($iter as $file) {
$files[] = $file;
}
sort($files, SORT_STRING);
return $files;
}
private function getFileIterator()
{
$factoryClass = class_exists('File_Iterator_Factory') ? 'File_Iterator_Factory' : 'SebastianBergmann\FileIterator\Factory';
$factory = new $factoryClass();
return $factory->getFileIterator($this->path, '.php');
}
public function getFactoryClass($file)
{
$name = $this->getFactoryClassName($file);
if ($name !== null) {
require_once $file;
if (class_exists($name)) {
$class = new FactoryClass(substr($file, strpos($file, 'Hamcrest/')), new ReflectionClass($name));
if ($class->isFactory()) {
return $class;
}
}
}
return null;
}
public function getFactoryClassName($file)
{
$content = file_get_contents($file);
if (preg_match('/namespace\s+(.+);/', $content, $namespace)
&& preg_match('/\n\s*class\s+(\w+)\s+extends\b/', $content, $className)
&& preg_match('/@factory\b/', $content)
) {
return $namespace[1] . '\\' . $className[1];
}
return null;
}
}

View File

@ -0,0 +1,231 @@
<?php
/*
Copyright (c) 2009 hamcrest.org
*/
/**
* Represents a single static factory method from a {@link Matcher} class.
*
* @todo Search method in file contents for func_get_args() to replace factoryVarArgs.
*/
class FactoryMethod
{
/**
* @var FactoryClass
*/
private $class;
/**
* @var ReflectionMethod
*/
private $reflector;
/**
* @var array of string
*/
private $comment;
/**
* @var bool
*/
private $isVarArgs;
/**
* @var array of FactoryCall
*/
private $calls;
/**
* @var array FactoryParameter
*/
private $parameters;
public function __construct(FactoryClass $class, ReflectionMethod $reflector)
{
$this->class = $class;
$this->reflector = $reflector;
$this->extractCommentWithoutLeadingShashesAndStars();
$this->extractFactoryNamesFromComment();
$this->extractParameters();
}
public function extractCommentWithoutLeadingShashesAndStars()
{
$this->comment = explode("\n", $this->reflector->getDocComment());
foreach ($this->comment as &$line) {
$line = preg_replace('#^\s*(/\\*+|\\*+/|\\*)\s?#', '', $line);
}
$this->trimLeadingBlankLinesFromComment();
$this->trimTrailingBlankLinesFromComment();
}
public function trimLeadingBlankLinesFromComment()
{
while (count($this->comment) > 0) {
$line = array_shift($this->comment);
if (trim($line) != '') {
array_unshift($this->comment, $line);
break;
}
}
}
public function trimTrailingBlankLinesFromComment()
{
while (count($this->comment) > 0) {
$line = array_pop($this->comment);
if (trim($line) != '') {
array_push($this->comment, $line);
break;
}
}
}
public function extractFactoryNamesFromComment()
{
$this->calls = array();
for ($i = 0; $i < count($this->comment); $i++) {
if ($this->extractFactoryNamesFromLine($this->comment[$i])) {
unset($this->comment[$i]);
}
}
$this->trimTrailingBlankLinesFromComment();
}
public function extractFactoryNamesFromLine($line)
{
if (preg_match('/^\s*@factory(\s+(.+))?$/', $line, $match)) {
$this->createCalls(
$this->extractFactoryNamesFromAnnotation(
isset($match[2]) ? trim($match[2]) : null
)
);
return true;
}
return false;
}
public function extractFactoryNamesFromAnnotation($value)
{
$primaryName = $this->reflector->getName();
if (empty($value)) {
return array($primaryName);
}
preg_match_all('/(\.{3}|-|[a-zA-Z_][a-zA-Z_0-9]*)/', $value, $match);
$names = $match[0];
if (in_array('...', $names)) {
$this->isVarArgs = true;
}
if (!in_array('-', $names) && !in_array($primaryName, $names)) {
array_unshift($names, $primaryName);
}
return $names;
}
public function createCalls(array $names)
{
$names = array_unique($names);
foreach ($names as $name) {
if ($name != '-' && $name != '...') {
$this->calls[] = new FactoryCall($this, $name);
}
}
}
public function extractParameters()
{
$this->parameters = array();
if (!$this->isVarArgs) {
foreach ($this->reflector->getParameters() as $parameter) {
$this->parameters[] = new FactoryParameter($this, $parameter);
}
}
}
public function getParameterDeclarations()
{
if ($this->isVarArgs || !$this->hasParameters()) {
return '';
}
$params = array();
foreach ($this->parameters as /** @var $parameter FactoryParameter */
$parameter) {
$params[] = $parameter->getDeclaration();
}
return implode(', ', $params);
}
public function getParameterInvocations()
{
if ($this->isVarArgs) {
return '';
}
$params = array();
foreach ($this->parameters as $parameter) {
$params[] = $parameter->getInvocation();
}
return implode(', ', $params);
}
public function getClass()
{
return $this->class;
}
public function getClassName()
{
return $this->class->getName();
}
public function getName()
{
return $this->reflector->name;
}
public function isFactory()
{
return count($this->calls) > 0;
}
public function getCalls()
{
return $this->calls;
}
public function acceptsVariableArguments()
{
return $this->isVarArgs;
}
public function hasParameters()
{
return !empty($this->parameters);
}
public function getParameters()
{
return $this->parameters;
}
public function getFullName()
{
return $this->getClassName() . '::' . $this->getName();
}
public function getCommentText()
{
return implode("\n", $this->comment);
}
public function getComment($indent = '')
{
$comment = $indent . '/**';
foreach ($this->comment as $line) {
$comment .= "\n" . rtrim($indent . ' * ' . $line);
}
$comment .= "\n" . $indent . ' */';
return $comment;
}
}

View File

@ -0,0 +1,131 @@
<?php
/*
Copyright (c) 2009 hamcrest.org
*/
class FactoryParameter
{
/**
* @var FactoryMethod
*/
private $method;
/**
* @var ReflectionParameter
*/
private $reflector;
public function __construct(FactoryMethod $method, ReflectionParameter $reflector)
{
$this->method = $method;
$this->reflector = $reflector;
}
/**
* Compute the declaration code.
*
* @return string
*/
public function getDeclaration()
{
$code = $this->getTypeCode() . $this->getInvocation();
if ($this->reflector->isOptional()) {
$default = $this->reflector->getDefaultValue();
if (is_null($default)) {
$default = 'null';
} elseif (is_bool($default)) {
$default = $default ? 'true' : 'false';
} elseif (is_string($default)) {
$default = "'" . $default . "'";
} elseif (is_numeric($default)) {
$default = strval($default);
} elseif (is_array($default)) {
$default = 'array()';
} else {
echo 'Warning: unknown default type for ' . $this->getMethod()->getFullName() . "\n";
var_dump($default);
$default = 'null';
}
$code .= ' = ' . $default;
}
return $code;
}
/**
* Compute the type code for the paramater.
*
* @return string
*/
private function getTypeCode()
{
// Handle PHP 5 separately
if (PHP_VERSION_ID < 70000) {
if ($this->reflector->isArray()) {
return 'array';
}
$class = $this->reflector->getClass();
return $class ? sprintf('\\%s ', $class->getName()) : '';
}
if (!$this->reflector->hasType()) {
return '';
}
$type = $this->reflector->getType();
$name = self::getQualifiedName($type);
// PHP 7.1+ supports nullable types via a leading question mark
return (PHP_VERSION_ID >= 70100 && $type->allowsNull()) ? sprintf('?%s ', $name) : sprintf('%s ', $name);
}
/**
* Compute qualified name for the given type.
*
* This function knows how to prefix class names with a leading slash and
* also how to handle PHP 8's union types.
*
* @param ReflectionType $type
*
* @return string
*/
private static function getQualifiedName(ReflectionType $type)
{
// PHP 8 union types can be recursively processed
if ($type instanceof ReflectionUnionType) {
return implode('|', array_map(function (ReflectionType $type) {
// The "self::" call within a Closure is fine here because this
// code will only ever be executed on PHP 7.0+
return self::getQualifiedName($type);
}, $type->getTypes()));
}
// PHP 7.0 doesn't have named types, but 7.1+ does
$name = $type instanceof ReflectionNamedType ? $type->getName() : (string) $type;
return $type->isBuiltin() ? $name : sprintf('\\%s', $name);
}
/**
* Compute the invocation code.
*
* @return string
*/
public function getInvocation()
{
return sprintf('$%s', $this->reflector->getName());
}
/**
* Compute the method name.
*
* @return string
*/
public function getMethod()
{
return $this->method;
}
}

View File

@ -0,0 +1,42 @@
<?php
/*
Copyright (c) 2009 hamcrest.org
*/
class GlobalFunctionFile extends FactoryFile
{
/**
* @var string containing function definitions
*/
private $functions;
public function __construct($file)
{
parent::__construct($file, ' ');
$this->functions = '';
}
public function addCall(FactoryCall $call)
{
$this->functions .= "\n" . $this->generateFactoryCall($call);
}
public function build()
{
$this->addFileHeader();
$this->addPart('functions_imports');
$this->addPart('functions_header');
$this->addCode($this->functions);
$this->addPart('functions_footer');
}
public function generateFactoryCall(FactoryCall $call)
{
$code = "if (!function_exists('{$call->getName()}')) {\n";
$code.= parent::generateFactoryCall($call);
$code.= "}\n";
return $code;
}
}

View File

@ -0,0 +1,38 @@
<?php
/*
Copyright (c) 2009 hamcrest.org
*/
class StaticMethodFile extends FactoryFile
{
/**
* @var string containing method definitions
*/
private $methods;
public function __construct($file)
{
parent::__construct($file, ' ');
$this->methods = '';
}
public function addCall(FactoryCall $call)
{
$this->methods .= PHP_EOL . $this->generateFactoryCall($call);
}
public function getDeclarationModifiers()
{
return 'public static ';
}
public function build()
{
$this->addFileHeader();
$this->addPart('matchers_imports');
$this->addPart('matchers_header');
$this->addCode($this->methods);
$this->addPart('matchers_footer');
}
}

View File

@ -0,0 +1,7 @@
<?php
/*
Copyright (c) 2009-2010 hamcrest.org
*/
// This file is generated from the static method @factory doctags.

View File

@ -0,0 +1,24 @@
if (!function_exists('assertThat')) {
/**
* Make an assertion and throw {@link Hamcrest_AssertionError} if it fails.
*
* Example:
* <pre>
* //With an identifier
* assertThat("assertion identifier", $apple->flavour(), equalTo("tasty"));
* //Without an identifier
* assertThat($apple->flavour(), equalTo("tasty"));
* //Evaluating a boolean expression
* assertThat("some error", $a > $b);
* </pre>
*/
function assertThat()
{
$args = func_get_args();
call_user_func_array(
array('Hamcrest\MatcherAssert', 'assertThat'),
$args
);
}
}

View File

@ -0,0 +1 @@
}

View File

@ -0,0 +1,7 @@
/**
* A series of static factories for all hamcrest matchers.
*/
class Matchers
{

View File

@ -0,0 +1,2 @@
namespace Hamcrest;

View File

@ -0,0 +1,37 @@
<?php
/*
Copyright (c) 2009 hamcrest.org
*/
require __DIR__ . '/../vendor/autoload.php';
/*
* Generates the Hamcrest\Matchers factory class and factory functions
* from the @factory doctags in the various matchers.
*/
define('GENERATOR_BASE', __DIR__);
define('HAMCREST_BASE', realpath(dirname(GENERATOR_BASE) . DIRECTORY_SEPARATOR . 'hamcrest'));
define('GLOBAL_FUNCTIONS_FILE', HAMCREST_BASE . DIRECTORY_SEPARATOR . 'Hamcrest.php');
define('STATIC_MATCHERS_FILE', HAMCREST_BASE . DIRECTORY_SEPARATOR . 'Hamcrest' . DIRECTORY_SEPARATOR . 'Matchers.php');
set_include_path(
implode(
PATH_SEPARATOR,
array(
GENERATOR_BASE,
HAMCREST_BASE,
get_include_path()
)
)
);
@unlink(GLOBAL_FUNCTIONS_FILE);
@unlink(STATIC_MATCHERS_FILE);
$generator = new FactoryGenerator(HAMCREST_BASE . DIRECTORY_SEPARATOR . 'Hamcrest');
$generator->addFactoryFile(new StaticMethodFile(STATIC_MATCHERS_FILE));
$generator->addFactoryFile(new GlobalFunctionFile(GLOBAL_FUNCTIONS_FILE));
$generator->generate();
$generator->write();