mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Add dummy --update-docblocks option
This commit is contained in:
parent
8c64dfd7fb
commit
8dfca6cce2
@ -19,7 +19,7 @@ ini_set('memory_limit', '2048M');
|
||||
ini_set('xdebug.max_nesting_level', 512);
|
||||
|
||||
// get options from command line
|
||||
$options = getopt('f:m:hc:', ['help', 'debug', 'config:', 'monochrome', 'show-info:', 'diff', 'file:', 'self-check']);
|
||||
$options = getopt('f:m:hc:', ['help', 'debug', 'config:', 'monochrome', 'show-info:', 'diff', 'file:', 'self-check', 'update-docblocks']);
|
||||
|
||||
if (array_key_exists('help', $options)) {
|
||||
$options['h'] = false;
|
||||
@ -112,6 +112,8 @@ $show_info = isset($options['show-info'])
|
||||
|
||||
$is_diff = isset($options['diff']);
|
||||
|
||||
$update_docblocks = isset($options['update-docblocks']);
|
||||
|
||||
// initialise custom config, if passed
|
||||
if ($path_to_config) {
|
||||
ProjectChecker::setConfigXML($path_to_config);
|
||||
@ -129,9 +131,9 @@ if (array_key_exists('self-check', $options)) {
|
||||
} elseif ($paths_to_check) {
|
||||
foreach ($paths_to_check as $path_to_check) {
|
||||
if (is_dir($path_to_check)) {
|
||||
ProjectChecker::checkDir($path_to_check, $debug);
|
||||
ProjectChecker::checkDir($path_to_check, $debug, $update_docblocks);
|
||||
} else {
|
||||
ProjectChecker::checkFile($path_to_check, $debug);
|
||||
ProjectChecker::checkFile($path_to_check, $debug, $update_docblocks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -202,6 +202,7 @@ abstract class ClassLikeChecker implements StatementsSource
|
||||
public function __construct(PhpParser\Node\Stmt\ClassLike $class, StatementsSource $source, $fq_class_name)
|
||||
{
|
||||
$this->class = $class;
|
||||
$this->source = $source;
|
||||
$this->namespace = $source->getNamespace();
|
||||
$this->aliased_classes = $source->getAliasedClasses();
|
||||
$this->file_name = $source->getFileName();
|
||||
@ -223,7 +224,7 @@ abstract class ClassLikeChecker implements StatementsSource
|
||||
* @param Context|null $class_context
|
||||
* @return false|null
|
||||
*/
|
||||
public function check($check_methods = true, Context $class_context = null)
|
||||
public function check($check_methods = true, Context $class_context = null, $update_docblocks = false)
|
||||
{
|
||||
if (!$check_methods &&
|
||||
!($this instanceof TraitChecker) &&
|
||||
@ -403,7 +404,7 @@ abstract class ClassLikeChecker implements StatementsSource
|
||||
$method_checker->check(clone $class_context);
|
||||
|
||||
if (!$config->excludeIssueInFile('InvalidReturnType', $this->file_name)) {
|
||||
$method_checker->checkReturnTypes();
|
||||
$method_checker->checkReturnTypes($update_docblocks);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -852,6 +853,14 @@ abstract class ClassLikeChecker implements StatementsSource
|
||||
return $this->aliased_classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getAliasedClassesFlipped()
|
||||
{
|
||||
return $this->source->getAliasedClassesFlipped();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
@ -29,15 +29,25 @@ class FileChecker implements StatementsSource
|
||||
protected $include_file_name;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $aliased_classes = [];
|
||||
|
||||
/**
|
||||
* @var array<string, array<int, string>>
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $aliased_classes_flipped = [];
|
||||
|
||||
/**
|
||||
* @var array<string, array<string, string>>
|
||||
*/
|
||||
protected $namespace_aliased_classes = [];
|
||||
|
||||
/**
|
||||
* @var array<string, array<string, string>>
|
||||
*/
|
||||
protected $namespace_aliased_classes_flipped = [];
|
||||
|
||||
/**
|
||||
* @var array<int, \PhpParser\Node>
|
||||
*/
|
||||
@ -116,6 +126,13 @@ class FileChecker implements StatementsSource
|
||||
*/
|
||||
protected static $deleted_files = null;
|
||||
|
||||
/**
|
||||
* A list of return types, keyed by file
|
||||
*
|
||||
* @var array<string, array<int, string>>
|
||||
*/
|
||||
protected static $docblock_return_types = [];
|
||||
|
||||
/**
|
||||
* @param string $file_name
|
||||
* @param array $preloaded_statements
|
||||
@ -140,8 +157,13 @@ class FileChecker implements StatementsSource
|
||||
* @param bool $cache
|
||||
* @return array|null
|
||||
*/
|
||||
public function check($check_classes = true, $check_functions = true, Context $file_context = null, $cache = true)
|
||||
{
|
||||
public function check(
|
||||
$check_classes = true,
|
||||
$check_functions = true,
|
||||
Context $file_context = null,
|
||||
$cache = true,
|
||||
$update_docblocks = false
|
||||
) {
|
||||
if ($cache && isset(self::$functions_checked[$this->short_file_name])) {
|
||||
return null;
|
||||
}
|
||||
@ -195,7 +217,7 @@ class FileChecker implements StatementsSource
|
||||
?: new ClassChecker($stmt, $this, $stmt->name);
|
||||
|
||||
$this->declared_classes[] = $class_checker->getFQCLN();
|
||||
$class_checker->check($check_functions);
|
||||
$class_checker->check($check_functions, null, $update_docblocks);
|
||||
}
|
||||
} elseif ($stmt instanceof PhpParser\Node\Stmt\Interface_) {
|
||||
if ($check_classes) {
|
||||
@ -218,11 +240,16 @@ class FileChecker implements StatementsSource
|
||||
$namespace_name = implode('\\', $stmt->name->parts);
|
||||
|
||||
$namespace_checker = new NamespaceChecker($stmt, $this);
|
||||
$this->namespace_aliased_classes[$namespace_name] = $namespace_checker->check(
|
||||
|
||||
$namespace_checker->check(
|
||||
$check_classes,
|
||||
$check_functions
|
||||
$check_functions,
|
||||
$update_docblocks
|
||||
);
|
||||
|
||||
$this->namespace_aliased_classes[$namespace_name] = $namespace_checker->getAliasedClasses();
|
||||
$this->namespace_aliased_classes_flipped[$namespace_name] = $namespace_checker->getAliasedClassesFlipped();
|
||||
|
||||
$this->declared_classes = array_merge($namespace_checker->getDeclaredClasses());
|
||||
} elseif ($stmt instanceof PhpParser\Node\Stmt\Function_ && $check_functions) {
|
||||
$function_context = new Context($this->short_file_name, $file_context->self);
|
||||
@ -426,7 +453,7 @@ class FileChecker implements StatementsSource
|
||||
|
||||
/**
|
||||
* @param string|null $namespace_name
|
||||
* @return array<string>
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getAliasedClasses($namespace_name = null)
|
||||
{
|
||||
@ -437,6 +464,19 @@ class FileChecker implements StatementsSource
|
||||
return $this->aliased_classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $namespace_name
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getAliasedClassesFlipped($namespace_name = null)
|
||||
{
|
||||
if ($namespace_name && isset($this->namespace_aliased_classes_flipped[$namespace_name])) {
|
||||
return $this->namespace_aliased_classes_flipped[$namespace_name];
|
||||
}
|
||||
|
||||
return $this->aliased_classes_flipped;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
@ -576,6 +616,7 @@ class FileChecker implements StatementsSource
|
||||
if ($stmt instanceof PhpParser\Node\Stmt\Use_) {
|
||||
foreach ($stmt->uses as $use) {
|
||||
$this->aliased_classes[strtolower($use->alias)] = implode('\\', $use->name->parts);
|
||||
$this->aliased_classes_flipped[implode('\\', $use->name->parts)] = $use->alias;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -842,4 +883,22 @@ class FileChecker implements StatementsSource
|
||||
{
|
||||
return md5($file_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a docblock to the given file
|
||||
* @param string $file_name
|
||||
* @param int $line_number
|
||||
* @param string $new_type
|
||||
*/
|
||||
public static function addDocblockReturnType($file_name, $line_number, $new_type)
|
||||
{
|
||||
if ($new_type === 'null') {
|
||||
$new_type = 'void';
|
||||
}
|
||||
|
||||
$new_type = str_replace('<mixed, mixed>', '', $new_type);
|
||||
|
||||
var_dump($file_name . ':' . $line_number . ' - ' . $new_type);
|
||||
self::$docblock_return_types[$file_name][$line_number] = $new_type;
|
||||
}
|
||||
}
|
||||
|
@ -343,13 +343,21 @@ abstract class FunctionLikeChecker implements StatementsSource
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string>
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getAliasedClasses()
|
||||
{
|
||||
return $this->source->getAliasedClasses();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getAliasedClassesFlipped()
|
||||
{
|
||||
return $this->source->getAliasedClassesFlipped();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
@ -442,10 +450,10 @@ abstract class FunctionLikeChecker implements StatementsSource
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $update_doc_comment
|
||||
* @param bool $update_docblock
|
||||
* @return false|null
|
||||
*/
|
||||
public function checkReturnTypes($update_doc_comment = false)
|
||||
public function checkReturnTypes($update_docblock = false)
|
||||
{
|
||||
if (!$this->function->getStmts()) {
|
||||
return null;
|
||||
@ -469,7 +477,7 @@ abstract class FunctionLikeChecker implements StatementsSource
|
||||
}
|
||||
}
|
||||
|
||||
if (!$method_return_types) {
|
||||
if (!$method_return_types && !$update_docblock) {
|
||||
if (IssueBuffer::accepts(
|
||||
new MissingReturnType(
|
||||
'Method ' . $cased_method_id . ' does not have a return type',
|
||||
@ -484,6 +492,35 @@ abstract class FunctionLikeChecker implements StatementsSource
|
||||
return null;
|
||||
}
|
||||
|
||||
$inferred_yield_types = [];
|
||||
$inferred_return_types = EffectsAnalyser::getReturnTypes(
|
||||
$this->function->getStmts(),
|
||||
$inferred_yield_types,
|
||||
true
|
||||
);
|
||||
|
||||
$inferred_return_type = $inferred_return_types ? Type::combineTypes($inferred_return_types) : null;
|
||||
$inferred_yield_type = $inferred_yield_types ? Type::combineTypes($inferred_yield_types) : null;
|
||||
|
||||
$inferred_generator_return_type = null;
|
||||
|
||||
if ($inferred_yield_type) {
|
||||
$inferred_generator_return_type = $inferred_return_type;
|
||||
$inferred_return_type = $inferred_yield_type;
|
||||
}
|
||||
|
||||
if (!$method_return_types && $update_docblock) {
|
||||
if ($inferred_return_type) {
|
||||
FileChecker::addDocblockReturnType(
|
||||
$this->file_name,
|
||||
$this->function->getLine(),
|
||||
$inferred_return_type->toNamespacedString($this->getAliasedClassesFlipped(), $this->getFQCLN())
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// passing it through fleshOutTypes eradicates errant $ vars
|
||||
$declared_return_type = ExpressionChecker::fleshOutTypes(
|
||||
$method_return_types,
|
||||
@ -492,32 +529,45 @@ abstract class FunctionLikeChecker implements StatementsSource
|
||||
$method_id
|
||||
);
|
||||
|
||||
if ($declared_return_type) {
|
||||
$inferred_yield_types = [];
|
||||
$inferred_return_types = EffectsAnalyser::getReturnTypes(
|
||||
$this->function->getStmts(),
|
||||
$inferred_yield_types,
|
||||
true
|
||||
);
|
||||
if (!$inferred_return_type && !$inferred_yield_types) {
|
||||
if ($declared_return_type->isVoid()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$inferred_return_types && !$inferred_yield_types) {
|
||||
if ($declared_return_type->isVoid()) {
|
||||
return null;
|
||||
}
|
||||
if (ScopeChecker::onlyThrows($this->function->getStmts())) {
|
||||
// if there's a single throw statement, it's presumably an exception saying this method is not to be
|
||||
// used
|
||||
return null;
|
||||
}
|
||||
|
||||
if (ScopeChecker::onlyThrows($this->function->getStmts())) {
|
||||
// if there's a single throw statement, it's presumably an exception saying this method is not to be
|
||||
// used
|
||||
return null;
|
||||
}
|
||||
if (IssueBuffer::accepts(
|
||||
new InvalidReturnType(
|
||||
'No return type was found for method ' . $cased_method_id .
|
||||
' but return type \'' . $declared_return_type . '\' was expected',
|
||||
$this->getCheckedFileName(),
|
||||
$this->function->getLine()
|
||||
)
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($inferred_return_type && !$declared_return_type->isMixed()) {
|
||||
if ($inferred_return_type->isNull() && $declared_return_type->isVoid()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($inferred_return_type->isMixed()) {
|
||||
if (IssueBuffer::accepts(
|
||||
new InvalidReturnType(
|
||||
'No return type was found for method ' . $cased_method_id .
|
||||
' but return type \'' . $declared_return_type . '\' was expected',
|
||||
new MixedInferredReturnType(
|
||||
'Could not verify return type \'' . $declared_return_type . '\' for ' .
|
||||
$cased_method_id,
|
||||
$this->getCheckedFileName(),
|
||||
$this->function->getLine()
|
||||
)
|
||||
),
|
||||
$this->getSuppressedIssues()
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
@ -525,58 +575,35 @@ abstract class FunctionLikeChecker implements StatementsSource
|
||||
return null;
|
||||
}
|
||||
|
||||
$inferred_return_type = $inferred_return_types ? Type::combineTypes($inferred_return_types) : null;
|
||||
if ($update_docblock) {
|
||||
if ((string)$inferred_return_type !== (string)$declared_return_type) {
|
||||
FileChecker::addDocblockReturnType(
|
||||
$this->file_name,
|
||||
$this->function->getLine(),
|
||||
$inferred_return_type->toNamespacedString($this->getAliasedClassesFlipped(), $this->getFQCLN())
|
||||
);
|
||||
}
|
||||
|
||||
$inferred_yield_type = $inferred_yield_types ? Type::combineTypes($inferred_yield_types) : null;
|
||||
|
||||
$inferred_generator_return_type = null;
|
||||
|
||||
if ($inferred_yield_type) {
|
||||
$inferred_generator_return_type = $inferred_return_type;
|
||||
$inferred_return_type = $inferred_yield_type;
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($inferred_return_type && !$declared_return_type->isMixed()) {
|
||||
if ($inferred_return_type->isNull() && $declared_return_type->isVoid()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($inferred_return_type->isMixed()) {
|
||||
if (IssueBuffer::accepts(
|
||||
new MixedInferredReturnType(
|
||||
'Could not verify return type \'' . $declared_return_type . '\' for ' .
|
||||
$cased_method_id,
|
||||
$this->getCheckedFileName(),
|
||||
$this->function->getLine()
|
||||
),
|
||||
$this->getSuppressedIssues()
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!TypeChecker::hasIdenticalTypes(
|
||||
$declared_return_type,
|
||||
$inferred_return_type,
|
||||
$this->fq_class_name
|
||||
if (!TypeChecker::hasIdenticalTypes(
|
||||
$declared_return_type,
|
||||
$inferred_return_type,
|
||||
$this->fq_class_name
|
||||
)) {
|
||||
if (IssueBuffer::accepts(
|
||||
new InvalidReturnType(
|
||||
'The given return type \'' . $declared_return_type . '\' for ' . $cased_method_id .
|
||||
' is incorrect, got \'' . $inferred_return_type . '\'',
|
||||
$this->getCheckedFileName(),
|
||||
$this->function->getLine()
|
||||
),
|
||||
$this->getSuppressedIssues()
|
||||
)) {
|
||||
if (IssueBuffer::accepts(
|
||||
new InvalidReturnType(
|
||||
'The given return type \'' . $declared_return_type . '\' for ' . $cased_method_id .
|
||||
' is incorrect, got \'' . $inferred_return_type . '\'',
|
||||
$this->getCheckedFileName(),
|
||||
$this->function->getLine()
|
||||
),
|
||||
$this->getSuppressedIssues()
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -24,10 +24,15 @@ class NamespaceChecker implements StatementsSource
|
||||
protected $declared_classes = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $aliased_classes = [];
|
||||
|
||||
/**
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $aliased_classes_flipped = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
@ -59,9 +64,9 @@ class NamespaceChecker implements StatementsSource
|
||||
/**
|
||||
* @param bool $check_classes
|
||||
* @param bool $check_class_statements
|
||||
* @return array
|
||||
* @return void
|
||||
*/
|
||||
public function check($check_classes = true, $check_class_statements = true)
|
||||
public function check($check_classes = true, $check_class_statements = true, $update_docblocks = false)
|
||||
{
|
||||
$leftover_stmts = [];
|
||||
|
||||
@ -76,7 +81,7 @@ class NamespaceChecker implements StatementsSource
|
||||
$class_checker = ClassLikeChecker::getClassLikeCheckerFromClass($fq_class_name)
|
||||
?: new ClassChecker($stmt, $this, $fq_class_name);
|
||||
|
||||
$class_checker->check($check_class_statements);
|
||||
$class_checker->check($check_class_statements, null, $update_docblocks);
|
||||
}
|
||||
} elseif ($stmt instanceof PhpParser\Node\Stmt\Interface_) {
|
||||
if ($check_classes) {
|
||||
@ -95,6 +100,7 @@ class NamespaceChecker implements StatementsSource
|
||||
} elseif ($stmt instanceof PhpParser\Node\Stmt\Use_) {
|
||||
foreach ($stmt->uses as $use) {
|
||||
$this->aliased_classes[strtolower($use->alias)] = implode('\\', $use->name->parts);
|
||||
$this->aliased_classes_flipped[implode('\\', $use->name->parts)] = strtolower($use->alias);
|
||||
}
|
||||
} else {
|
||||
$leftover_stmts[] = $stmt;
|
||||
@ -106,8 +112,6 @@ class NamespaceChecker implements StatementsSource
|
||||
$context = new Context($this->file_name);
|
||||
$statments_checker->check($leftover_stmts, $context);
|
||||
}
|
||||
|
||||
return $this->aliased_classes;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,6 +149,14 @@ class NamespaceChecker implements StatementsSource
|
||||
return $this->aliased_classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAliasedClassesFlipped()
|
||||
{
|
||||
return $this->aliased_classes_flipped;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
|
@ -35,7 +35,7 @@ class ProjectChecker
|
||||
* @param boolean $is_diff
|
||||
* @return void
|
||||
*/
|
||||
public static function check($debug = false, $is_diff = false)
|
||||
public static function check($debug = false, $is_diff = false, $update_docblocks = false)
|
||||
{
|
||||
$cwd = getcwd();
|
||||
|
||||
@ -65,7 +65,7 @@ class ProjectChecker
|
||||
|
||||
if ($diff_files === null || $deleted_files === null || count($diff_files) > 200) {
|
||||
foreach (self::$config->getIncludeDirs() as $dir_name) {
|
||||
self::checkDirWithConfig($dir_name, self::$config, $debug);
|
||||
self::checkDirWithConfig($dir_name, self::$config, $debug, $update_docblocks);
|
||||
}
|
||||
} else {
|
||||
if ($debug) {
|
||||
@ -121,7 +121,7 @@ class ProjectChecker
|
||||
* @param bool $debug
|
||||
* @return void
|
||||
*/
|
||||
protected static function checkDirWithConfig($dir_name, Config $config, $debug)
|
||||
protected static function checkDirWithConfig($dir_name, Config $config, $debug, $update_docblocks)
|
||||
{
|
||||
$file_extensions = $config->getFileExtensions();
|
||||
$filetype_handlers = $config->getFiletypeHandlers();
|
||||
@ -147,7 +147,7 @@ class ProjectChecker
|
||||
$file_checker = new FileChecker($file_name);
|
||||
}
|
||||
|
||||
$file_checker->check(true);
|
||||
$file_checker->check(true, true, null, true, $update_docblocks);
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,7 +266,7 @@ class ProjectChecker
|
||||
* @param boolean $debug
|
||||
* @return void
|
||||
*/
|
||||
public static function checkFile($file_name, $debug = false)
|
||||
public static function checkFile($file_name, $debug = false, $update_docblocks = false)
|
||||
{
|
||||
if ($debug) {
|
||||
echo 'Checking ' . $file_name . PHP_EOL;
|
||||
@ -295,7 +295,7 @@ class ProjectChecker
|
||||
$file_checker = new FileChecker($file_name);
|
||||
}
|
||||
|
||||
$file_checker->check(true);
|
||||
$file_checker->check(true, true, null, true, $update_docblocks);
|
||||
|
||||
IssueBuffer::finish();
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ class TraitChecker extends ClassLikeChecker
|
||||
* @param Context|null $class_context
|
||||
* @return void
|
||||
*/
|
||||
public function check($check_methods = true, Context $class_context = null)
|
||||
public function check($check_methods = true, Context $class_context = null, $update_docblocks = false)
|
||||
{
|
||||
if (!$class_context) {
|
||||
throw new \InvalidArgumentException('TraitChecker::check must be called with a $class_context');
|
||||
|
@ -30,6 +30,23 @@ class Atomic extends Type
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function toNamespacedString(array $aliased_classes, $this_class)
|
||||
{
|
||||
if ($this->value === $this_class) {
|
||||
return $this_class;
|
||||
}
|
||||
|
||||
if (isset($aliased_classes[$this->value])) {
|
||||
return $aliased_classes[$this->value];
|
||||
}
|
||||
|
||||
if ($this->isObjectType()) {
|
||||
return '\\' . $this->value;
|
||||
}
|
||||
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Union $parent
|
||||
* @return bool
|
||||
|
@ -28,7 +28,7 @@ class Generic extends Atomic
|
||||
return $this->value .
|
||||
'<' .
|
||||
implode(
|
||||
',',
|
||||
', ',
|
||||
array_map(
|
||||
function ($type_param) {
|
||||
return (string) $type_param;
|
||||
@ -38,4 +38,23 @@ class Generic extends Atomic
|
||||
) .
|
||||
'>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function toNamespacedString(array $aliased_classes, $this_class)
|
||||
{
|
||||
return $this->value .
|
||||
'<' .
|
||||
implode(
|
||||
', ',
|
||||
array_map(
|
||||
function ($type_param) use ($aliased_classes, $this_class) {
|
||||
return $type_param->toNamespacedString($aliased_classes, $this_class);
|
||||
},
|
||||
$this->type_params
|
||||
)
|
||||
) .
|
||||
'>';
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ class ObjectLike extends Atomic
|
||||
return $this->value .
|
||||
'{' .
|
||||
implode(
|
||||
',',
|
||||
', ',
|
||||
array_map(
|
||||
function ($name, $type) {
|
||||
return $name . ':' . $type;
|
||||
@ -43,4 +43,24 @@ class ObjectLike extends Atomic
|
||||
) .
|
||||
'}';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function toNamespacedString(array $aliased_classes, $this_class)
|
||||
{
|
||||
return $this->value .
|
||||
'{' .
|
||||
implode(
|
||||
', ',
|
||||
array_map(
|
||||
function ($name, $type) use ($aliased_classes, $this_class) {
|
||||
return $name . ':' . $type->toNamespacedString($aliased_classes, $this_class);
|
||||
},
|
||||
array_keys($this->properties),
|
||||
$this->properties
|
||||
)
|
||||
) .
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,20 @@ class Union extends Type
|
||||
'|',
|
||||
array_map(
|
||||
function ($type) {
|
||||
return (string) $type;
|
||||
return (string)$type;
|
||||
},
|
||||
$this->types
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function toNamespacedString(array $aliased_classes, $this_class)
|
||||
{
|
||||
return implode(
|
||||
'|',
|
||||
array_map(
|
||||
function ($type) use ($aliased_classes, $this_class) {
|
||||
return $type->toNamespacedString($aliased_classes, $this_class);
|
||||
},
|
||||
$this->types
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user